MVC 之AjaxHelper
Posted 在西天取经的路上……
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MVC 之AjaxHelper相关的知识,希望对你有一定的参考价值。
除了传统的Ajax方法之外,MVC提供了AjaxHelper类:
使用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 |
以上是关于MVC 之AjaxHelper的主要内容,如果未能解决你的问题,请参考以下文章
ASP.net MVC 代码片段问题中的 Jqgrid 实现
[Angularjs]asp.net mvc+angularjs+web api单页应用之CRUD操作
MvcPager 概述 MvcPager 分页示例 — 标准Ajax分页 对SEO进行优化的ajax分页 (支持asp.net mvc)