Billpeng Space

技术源自生活
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

MVC 之AjaxHelper

Posted on 2013-10-09 10:23  billpeng  阅读(395)  评论(0编辑  收藏  举报

http://www.cnblogs.com/jyan/archive/2012/07/23/2604958.html

 

除了传统的Ajax方法之外,MVC提供了AjaxHelper类:

Helper method Description
Ajax.ActionLink Creates a hyperlink to a controller action that fires an Ajax request when clicked
Ajax.RouteLink Similar to Ajax.ActionLink, but generates a link to a particular route instead of a named controller action
Ajax.BeginForm Creates a form element that submits its data to a particular controller action using Ajax
Ajax.BeginRouteForm Similar to Ajax.BeginForm, but creates a form that sub- mits its data to a particular route instead of a named control- ler action
Ajax.GlobalizationScript Creates an HTML script element that references a script that contains culture information
Ajax.JavaScriptStringEncode Encodes a string to make sure that it can safely be used inside JavaScript


   

 

 

 

 

 

 

 

 

使用AjaxHelper可以很方便的实现Ajax请求,Aps.net MVC提供了jQuery和Microsoft Ajax类库两种方式来实现,使用何种方式取决于我们Web.config配置:

 

 <add key="UnobtrusiveJavaScriptEnabled" value="true" />

 

当设置为true时,将使用jQuery方式实现请求,生成的链接如下:

 <a data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#test" href="http://www.cnblogs.com/">测试</a>

 

反之则使用Microsoft Ajax类库实现

 

<a href="http://www.cnblogs.com/" onclick="Sys.Mvc.AsyncHyperlink.handleClick(this, new Sys.UI.DomEvent(event), { insertionMode: Sys.Mvc.InsertionMode.replace, httpMethod: 'GET', updateTargetId: 'test' });">测试</a>

 

在我们创建项目时,该值默认为true。这种情况下吗,我们要在页面中引入相应的js类库:

 

@section scripts{
    <script type="text/javascript" src=" @Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")"></script>
}

 

下面重点了解Ajax.ActionLink()和Ajax.BeginForm()这两个Helper.

Ajax.ActionLink():

  向客户端输入一个链接地址,当单击这个链接时可以异步调用Controller中的方法,Ajax.ActionLink()方法有许多重载,我们这里举例说明其中一个比较常用的重载:

 

  public static string ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, object routeValues, AjaxOptions ajaxOptions);

 

  linkText:是显示在客户端的文本

 

  actionName:是Action的名字,默认情况下我们会使用当前的Controller。

 

  routeValues:将传入到Controller中方法的参数

 

  ajaxOptions:配置Ajax的一些选项,看完下面的例子我们再详细讲解这个配置选项。

参数
Confirm 获取或设置提交请求之前,显示在确认窗口中的消息。
HttpMethod 获取或设置 HTTP 请求方法(“Get”或“Post”)。
InsertionMode 获取或设置指定如何将响应插入目标 DOM 元素的模式。
LoadingElementId 获取或设置加载 Ajax 函数时要显示的 HTML 元素的 id 特性。
OnBegin 获取或设置更新页面之前,恰好调用的 JavaScript 函数的名称。
OnComplete 获取或设置实例化响应数据之后但更新页面之前,要调用的 JavaScript 函数。
OnFailure 获取或设置页面更新失败时,要调用的 JavaScript 函数。
OnSuccess 获取或设置成功更新页面之后,要调用的 JavaScript 函数。
UpdateTargetId 获取或设置要使用服务器响应来更新的 DOM 元素的 ID。
Url 获取或设置要向其发送请求的 URL。

以之前的GuestBook为例,在列表页面(Index.cshtml),使用Ajax来显示选中行的详细信息:

Index.cshtml页面源码:

复制代码
@foreach (MvcApplication5.Models.GuestbookEntry item in ViewBag.Entries)
{
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Name)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Message)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.DateAdded)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
            @Html.ActionLink("Details", "Details", new { id=item.Id }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.Id }) |
            @Ajax.ActionLink("AjaxContentController", "getEntry", new { id = item.Id }, new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "detailsID", InsertionMode = InsertionMode.Replace })
            @Ajax.ActionLink("AjaxJsonController", "JsonDetails", new { id = item.Id }, new AjaxOptions { HttpMethod = "Post", InsertionMode = InsertionMode.Replace, OnSuccess = "Show" })
            @Ajax.ActionLink("AjaxPartialView", "Details", new { id = item.Id }, new AjaxOptions { HttpMethod = "Get", UpdateTargetId = "detailsID" })
        </td>
    </tr>
}

</table>
<div id="detailsID"></div>
复制代码

 

 

我们将使用ActionLink分别异步请求ContentController,Json格式的Controller和PartialView格式的Controller来显示详细信息:

1:Ajax异步请求ContentController

ContentController直接以字符串形式返回实例的内容,在Index.cshtml中使用ActionLink,如下:

@Ajax.ActionLink("AjaxContentController", "getEntry", new { id = item.Id }, new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "detailsID", InsertionMode = InsertionMode.Replace })

相应的Controller:

public string getEntry(int id = 0) {
            GuestbookEntry entry = _db.Entries.First(c => c.Id == id);
            return entry.Details;
}

结果:返回的内容直接更新到ID属性为detailsID的DIV中:

2: 使用Json格式返回

在Index.cshtml中使用ActionLink,如下:

 

@Ajax.ActionLink("AjaxJsonController", "JsonDetails", new { id = item.Id }, new AjaxOptions { HttpMethod = "Post", InsertionMode = InsertionMode.Replace, OnSuccess = "Show" })

 

相应的Controller:

 public ActionResult JsonDetails(int id = 0)
        {
            GuestbookEntry entry = _db.Entries.First(c => c.Id == id);
            return Json(entry, JsonRequestBehavior.AllowGet);
        }

注意:在使用Json格式返回数据时,由于安全原因,只接收Post请求,因此在这里使用JsonRequestBehavior.AllowGet来允许Get方式请求。

同时需要在Index.cshtml中添加请求成功的相应函数Show:

<script type="text/javascript">
        function Show(data) {
            $("#detailsID").html("姓名:" + data.Name + " 消息:" + data.Message);
        }
 </script>

结果:在响应函数中更新ID属性为detailsID的DIV内容:

3使用PartialView来返回数据

PartialView类似于WebForms中的用户自定义控件,可以用来显示一些公共的信息。在Index.cshtml中

@Ajax.ActionLink("AjaxPartialView", "Details", new { id = item.Id }, new AjaxOptions { HttpMethod = "Get", UpdateTargetId = "detailsID" })

相应的Controller:

复制代码
public ActionResult Details(int id = 0)
        {
            GuestbookEntry entry = _db.Entries.First(c => c.Id == id);
            if (Request.IsAjaxRequest())
            {
                return PartialView(entry);
            }
            return View(entry);
        }
复制代码

在这里我们使用Request.IsAjaxRequest()来判断是否为Ajax请求,如果是则返回PartialView,否则返回View

结果:返回的内容直接更新到ID属性为detailsID的DIV中:

 

 

 Ajax.BeginForm

打开Create.cshtml页面,现在的页面使用的是Html.BeginForm()进行表单提交的,下面我们将它修改为Ajax方式提交

 

 

复制代码
@model MvcApplication5.Models.GuestbookEntry

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>GuestbookEntry</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Message)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Message)
            @Html.ValidationMessageFor(model => model.Message)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}
复制代码

 

修改后的页面如下:

复制代码
@model MvcApplication5.Models.GuestbookEntry
<script type="text/javascript" src=" @Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")"></script>
<script type="text/javascript">
    function success(data) {
        alert(data);
    }
</script>
@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

@using (Ajax.BeginForm(new AjaxOptions { 
    HttpMethod="Post",
    OnSuccess = "success"
}))
{
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>GuestbookEntry</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Message)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Message)
            @Html.ValidationMessageFor(model => model.Message)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}
复制代码

 

而相应的Controller没有任何变化。

 

复制代码
[HttpPost]
        public ActionResult Create(GuestbookEntry entry)
        {

            if (ModelState.IsValid)
            {
                entry.DateAdded = DateTime.Now;
                _db.Entries.Add(entry);
                _db.SaveChanges();
                return Content("New Entry successfully added.");
            }
            else {
                return View();
            }
        }
复制代码

 附注:

在web.config中增加client side validation and unobtrusive javascript 两个配置
<add key="ClientValidationEnabled" value="true" /> 
<add key="UnobtrusiveJavaScriptEnabled" value="true" /> 
客户端验证是基于jquery.validate.js和jquery.validate.unobtrusive.js的,当你在一个view中包含了这两个文件时,你在Model中声明的data annotation才会被解析。这时你打开你表单查看页面的源代码,可以看到相应的input fields都具有包含验证规则的HTML5的data-*属性,这些属性将被Microsoft unobtrusive validation script读取并配置jquery validate.
unobtrusive javascript 是基于jQuery的,在使用AjaxHelper时(ActionLink 或者BeginForm),他会自动向你的控件中添加data-属性(HTML5 属性),这些属性之后会被jquery.unobtrusive-ajax.js进行解析,所以要在页面中引入该文件。
例如:
@Ajax.ActionLink("UTC", "GetTime", new { zone = "utc" }, new AjaxOptions { UpdateTargetId = "myResults" })
生成的代码是:
<a data-ajax="true" data-ajax-mode="replace" data-ajax-update="#myResults" href="/Home/GetTime?zone=utc">UTC</a>
jquery.unobtrusive-ajax.js作用就是解析data-ajax-mode等属性,然后发出ajax请求的(可以看下这个文件的代码),乱码就是因为你没有引入该文件
如果不想使用jquery,改为false即可
<add key="UnobtrusiveJavaScriptEnabled" value="false" /> 
同时需要在页面中引入MicrosoftAjax.js,MicrosoftMvcAjax.js