除了傳統的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 |