ASP.NET MVC 4 (八) URL链接和Ajax帮助函数
来源:互联网 发布:安卓游戏市场 知乎 编辑:程序博客网 时间:2024/04/29 00:35
http://www.cnblogs.com/duanshuiliu/p/3702835.html
MVC提供一些帮助函数创建链接,这些函数根据路径映射表自动调整生成的URL:
说明示例输出结果应用程序相对URLUrl.Content("~/Content/Site.css") /Content/Site.css到控制器action的链接Html.ActionLink("My Link", "Index", "Home")<a href="/">My Link</a> Action的URLUrl.Action("GetPeople", "People")/People/GetPeople 使用路径映射的URLUrl.RouteUrl(new {controller = "People", action="GetPeople"}) /People/GetPeople 使用路径映射的链接Html.RouteLink("My Link", new {controller = "People", action="GetPeople"})
<a href="/People/GetPeople">My Link</a>命名路径映射的链接Html.RouteLink("My Link", "FormRoute", new {controller = "People", action="GetPeople"})
<a href="/app/forms/People/GetPeople">My Link</a>使用MVC Unobtrusive Ajax
MVC内建基于jQuery的unobtrusive Ajax的支持,之所以称之为unobtrusive Ajax是因为不像常规Ajax那样大量使用XML。要使用unobtrusive Ajax,首先需要在web.config的 configuration/appSettings一节开启UnobtrusiveJavaScriptEnabled支持:
... <configuration> <!-- other elements omitted for brevity --> <appSettings> <add key="webpages:Version" value="2.0.0.0" /> <add key="webpages:Enabled" value="false" /> <add key="PreserveLoginUrl" value="true" /> <add key="ClientValidationEnabled" value="true" /> <add key="UnobtrusiveJavaScriptEnabled" value="true" /> </appSettings> <!-- other elements omitted for brevity --> </configuration> ...
同时我们需要引用相关的javascript文件,可以把对这些脚本文件的引用放到布局文件_layout.cshtml中:
<!DOCTYPE html><html><head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <title>@ViewBag.Title</title> <link href="~/Content/Site.css" rel="stylesheet"/> <script src="~/Scripts/jquery-1.7.1.min.js" type="text/javascript"></script> <script src="~/Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script></head><body> @RenderBody()</body></html>
jquery-1.7.1.min.js为jQuery的核心库,jquery.unobtrusive-ajax.min.js则提供Ajax功能(基于jquery库),文件名中的.min表示几乎不可能调试的缩减版本,可以在开发时使用非.min版本,发布时再采用.min版本。
使用Unobtrusive Ajax表单
下面以实例演示如何使用Ajax表单,从控制器开始:
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using HelperMethods.Models;namespace HelperMethods.Controllers{ public class PeopleController : Controller { private Person[] personData = { new Person {FirstName = "Adam", LastName = "Freeman", Role = Role.Admin}, new Person {FirstName = "Steven", LastName = "Sanderson", Role = Role.Admin}, new Person {FirstName = "Jacqui", LastName = "Griffyth", Role = Role.User}, new Person {FirstName = "John", LastName = "Smith", Role = Role.User}, new Person {FirstName = "Anne", LastName = "Jones", Role = Role.Guest} }; public ActionResult Index() { return View(); } public PartialViewResult GetPeopleData(string selectedRole = "All") { IEnumerable<Person> data = personData; if (selectedRole != "All") { Role selected = (Role)Enum.Parse(typeof(Role), selectedRole); data = personData.Where(p => p.Role == selected); } return PartialView(data); } public ActionResult GetPeople(string selectedRole = "All") { return View((object)selectedRole); } }}
GetPeopleData()方法根据选择的角色过滤Person列表,返回一个分部视图,对应的GetPeopleData.cshtml:
@using HelperMethods.Models@model IEnumerable<Person>@foreach (Person p in Model) { <tr> <td>@p.FirstName</td> <td>@p.LastName</td> <td>@p.Role</td> </tr> }
在Getpeople视图中我们调用GetPeopleData()同时创建一个Ajax form:
@using HelperMethods.Models@model string@{ ViewBag.Title = "GetPeople"; AjaxOptions ajaxOpts = new AjaxOptions { UpdateTargetId = "tableBody" };}<h2>Get People</h2><table> <thead><tr><th>First</th><th>Last</th><th>Role</th></tr></thead> <tbody id="tableBody"> @Html.Action("GetPeopleData", new { selectedRole = Model }) </tbody></table>@using (Ajax.BeginForm("GetPeopleData", ajaxOpts)){ <div> @Html.DropDownList("selectedRole", new SelectList(new[] { "All" }.Concat(Enum.GetNames(typeof(Role))))) <button type="submit">Submit</button> </div>}
Ajax.BeginForm()创建一个Ajax form,使用AjaxOptions对象作为参数,生成的HTML结果:
... <form action="/People/GetPeopleData" data-ajax="true" data-ajax-mode="replace" data-ajax-update="#tableBody"id="form0" method="post"> ...
浏览器请求GetPeople页面时jquery.unobtrusive-ajax.js扫描data-ajax=true的单元,以此确认这是一个ajax的表单,点击提交时不刷新整个页面,而是用从/people/getpeopledata返回的结果替换tablebody的内容。
Ajax options
AjaxOptions控制向服务器异步请求时的方式,包含这些属性:
属性说明Confirm在开始异步请求时向用户显示一条消息以确认HttpMethod设置请求的HTTP方法,必须是get或者postInsertionMode如何嵌入服务器结果返回的HTML,可以是InsertAfter、InsertBefore、Replace(默认)LoadingElementId指定Ajax请求时要显示的Loading单元元素IDLoadingElementDurationLoading元素动画显示的时长UpdateTargetId请求返回结果要插入的元素IDUrlAjax表单提交的URL上面的GetPeople视图Ajax form提交的URL是/People/GetPeopleData,如果用户禁止了java脚本,提交form返回的结果会只是GetPeopleData分部视图,我们可以直接在ajaxOptions指定ajax请求的URL来解决:
@using HelperMethods.Models@model string@{ ViewBag.Title = "GetPeople"; AjaxOptions ajaxOpts = new AjaxOptions { UpdateTargetId = "tableBody", Url = Url.Action("GetPeopleData"), LoadingElementId = "loading", LoadingElementDuration = 1000, Confirm = "Do you wish to request new data?" };}<h2>Get People</h2><div id="loading" class="load" style="display:none"> <p>Loading Data...</p></div><table> <thead><tr><th>First</th><th>Last</th><th>Role</th></tr></thead> <tbody id="tableBody"> @Html.Action("GetPeopleData", new { selectedRole = Model }) </tbody></table>@using (Ajax.BeginForm(ajaxOpts)){ <div> @Html.DropDownList("selectedRole", new SelectList(new[] { "All" }.Concat(Enum.GetNames(typeof(Role))))) <button type="submit">Submit</button> </div>}
生成的表单HTML:
... <form action="/People/GetPeople"data-ajax="true" data-ajax-mode="replace" data-ajax-update="#tableBody" data-ajax-url="/People/GetPeopleData"id="form0" method="post"> ...
这样表单提交的URL依然是/People/GetPeople,即使禁止了java脚本返回的仍然是GetPeople页面,ajax请求的URL通过data-ajax-url指定为/People/GetPeopleData。我们还设置 AjaxOptions.LoadingElementId为Loading,这是一个diplay:none风格的DIV元素,它只在AJAX异步请求时显示一秒钟(LoadingElementDuration = 1000)。AjaxOptions.Confirm= "Do you wish to request new data?" ,在每次Ajax请求时都会弹出网页Message对话框询问(对话框消息为这里设定的"Do you wish to request new data?")。
Ajax链接
上面的例子中我们使用表单提交数据,如果是使用链接做ajax异步请求可以这样操作:
...<div> @foreach (string role in Enum.GetNames(typeof(Role))) { <div class="ajaxLink"> @Ajax.ActionLink(role, "GetPeopleData", new {selectedRole = role}, new AjaxOptions {UpdateTargetId = "tableBody"}) </div> } </div> ...
这里对role枚举中每个元素生成一个链接,生成的链接元素类似:
... <a data-ajax="true" data-ajax-mode="replace" data-ajax-update="#tableBody" href="/People/GetPeopleData?selectedRole=Guest">Guest</a> ...
点击某个链接时ajax返回的HTML数据会用于替换tableBody元素,和使用表单提交ajax请求效果一样。同样如果禁用了java脚本,返回的结果会只是getpeopledata分部视图,我们可以这样改进:
<div> @foreach (string role in Enum.GetNames(typeof(Role))) { <div class="ajaxLink"> @Ajax.ActionLink(role, "GetPeople", new {selectedRole = role}, new AjaxOptions { UpdateTargetId = "tableBody", Url = Url.Action("GetPeopleData", new {selectedRole = role}) }) </div> } </div>
链接请求的地址是GetPeople,Ajax请求的URL则仅是GetPeopleData,请求的HTML结果作用于tablebody。
Ajax回调
AjaxOptions类暴露一组属性允许我们指定一个java脚本函数,在ajax请求周期中调用这些脚本函数:
属性jQuery事件说明OnBeginbeforeSend在Ajax请求发送前调用OnCompletecomplete请求成功时调用OnFailureerror请求失败时调用OnSuccesssuccess无论请求成功与否都在请求完成时调用结合回调函数我们可以对上面的例子进一步修改,首先修改控制器的GetPeopleData方法:
public ActionResult GetPeopleData(string selectedRole = "All") { IEnumerable<Person> data = personData; if (selectedRole != "All") { Role selected = (Role)Enum.Parse(typeof(Role), selectedRole); data = personData.Where(p => p.Role == selected); } if (Request.IsAjaxRequest()) { var formattedData = data.Select(p => new { FirstName = p.FirstName, LastName = p.LastName, Role = Enum.GetName(typeof(Role), p.Role) }); return Json(formattedData, JsonRequestBehavior.AllowGet); } else { return PartialView(data); } }
我们使用Request.IsAjaxRequest判断请求是否来自于ajax,它的依据是浏览器在ajax请求时在头中会包含X-Requested-With=XMLHttpRequest。如果请求来自于ajax,控制器方法返回的是Json(data, JsonRequestBehavior.AllowGet)创建的JsonResult对象,默认JSON数据只在POST请求中发送,这里在第二个参数中指定JsonRequestBehavior.AllowGet允许在GET请求中使用JSON数据。MVC框架负责对formattedData做json封装,封装的格式由MVC尝试使用最适宜的方法确定,这里返回的JSON数据类似:
... {"PersonId":0,"FirstName":"Adam","LastName":"Freeman", "BirthDate":"\/Date(62135596800000)\/","HomeAddress":null,"IsApproved":false,"Role":0} ...
视图中我们在AjaxOptions的OnSucess回调函数中处理返回的JSON数据:
@using HelperMethods.Models@model string@{ ViewBag.Title = "GetPeople"; AjaxOptions ajaxOpts = new AjaxOptions { //UpdateTargetId = "tableBody", Url = Url.Action("GetPeopleData"), LoadingElementId = "loading", LoadingElementDuration = 1000, OnSuccess = "processData" };}<script type="text/javascript"> function processData(data) { var target = $("#tableBody"); target.empty(); for (var i = 0; i < data.length; i++) { var person = data[i]; target.append("<tr><td>" + person.FirstName + "</td><td>" + person.LastName + "</td><td>" + person.Role + "</td></tr>"); } }</script><h2>Get People</h2><div id="loading" class="load" style="display: none"> <p>Loading Data...</p></div><table> <thead> <tr> <th>First</th> <th>Last</th> <th>Role</th> </tr> </thead> <tbody id="tableBody"> @Html.Action("GetPeopleData", new { selectedRole = Model }) </tbody></table>@using (Ajax.BeginForm(ajaxOpts)){ <div> @Html.DropDownList("selectedRole", new SelectList(new[] { "All" }.Concat(Enum.GetNames(typeof(Role))))) <button type="submit">Submit</button> </div> }<div> @foreach (string role in Enum.GetNames(typeof(Role))) { <div class="ajaxLink"> @Ajax.ActionLink(role, "GetPeople",new { selectedRole = role },new AjaxOptions{ Url = Url.Action("GetPeopleData", new { selectedRole = role }), OnSuccess = "processData"}) </div> }</div>
脚本函数processData在AjaxOptions的OnSuccess回调时调用,它负责处理请求返回的JSON数据,从中分拆出各个Person对象,根据这些数据直接改写tableBody标签的内容,因此我们不再需要在AjaxOptions通过UpdateTargetId指定要替换内容的元素。
以上为对《Apress Pro ASP.NET MVC 4》第四版相关内容的总结,不详之处参见原版 http://www.apress.com/9781430242369。
- ASP.NET MVC 4 (八) URL链接和Ajax帮助函数
- ASP.NET MVC 4 (八) URL链接和Ajax帮助函数
- ASP.NET MVC 4 (六) 帮助函数
- ASP.NET MVC 4 (七) 模板帮助函数
- ASP.NET MVC和AJAX
- Asp.net MVC 4 Html帮助类
- ASP.NET MVC HandleErrorAttribute 和 远程链接
- ASP.NET MVC的帮助类HtmlHelper和UrlHelper
- ASP.NET MVC URL Routing
- asp.net mvc css url
- Asp.net MVC 4 Html帮助类 II
- 12月16日链接篇: ASP.NET, ASP.NET AJAX, ASP.NET MVC, VS, .NET, IIS7, WPF
- jQuery和asp.net mvc相关资源链接
- asp.net mvc ajax 例子
- asp.net mvc ajax 例子
- Asp.Net Mvc Ajax偏方
- ASP.NET MVC之Ajax
- 关于ASP.NET MVC和NHibernate,LinQ,ASP.NET AJAX,ASP.NET Custom Server Control
- 线性表、栈、队列
- sscanf函数的用法
- Oracle 11g 学习六:表的创建及管理
- 接口
- C语言有哪些取整函数?
- ASP.NET MVC 4 (八) URL链接和Ajax帮助函数
- 在使用SQLite插入数据时出现乱码的解决办法
- 01背包
- 老婆常说韩国女孩漂亮
- struct和typedef struct
- 户籍科技阳谷华泰
- 归并排序
- 企业研发管理过程能力成熟度的比较
- 真正的软件工程工作到底是什么样的?