Loading Data
First Last Role @Html.Action("GetPeopleData", new { selectedRole = Model }) @using (Ajax.BeginForm(ajaxOpts)) { @Html.DropDownList("selectedRole", new SelectList( new[] { "All" }.Concat(Enum.GetNames(typeof(Role))))) Submit } @foreach (string role in Enum.GetNames(typeof(Role))) { @Ajax.ActionLink(role, "GetPeople", new { selectedRole = role }, new AjaxOptions { UpdateTargetId = "tableBody", Url = Url.Action("GetPeopleData", new { selectedRole = role }), OnBegin = "OnBegin", OnFailure = "OnFailure", OnSuccess = "OnSuccess", OnComplete = "OnComplete" }) } Tôi định nghĩa bốn chức năng, cho callback Với ví dụ này, đơn giản dễ hiểu hiển thị thông báo cho người sử dụng chức Với thay đổi này, nhấp vào liên kết hiển thị chuỗi hộp thội để báo cáo tiến độ yêu cầu Ajax, thể hình 23-8 Hiển thị hộp thoại cho người dùng cho callback điều hay để làm với Ajax callbacks, thể trình tự mà chúng gọi Những chức Javascript dùng với mục đích nào: thao tác với HTML DOM, kích hoạt yêu cầu bổ sung, v.v Một điều hữu ích để làm với callbacks xử lý liệu JSON, thứ mà mô tả phần Làm việc với JSON Cho đến ví dụ Ajax, máy chủ tạo mảnh HTML gửi chúng đến trình duyệt Đây kỹ thuật hoàn toàn chấp nhận được, rườm rà, dài dòng (vì máy chủ gửi yếu tố HTML với liệu) hạn chế thực với liệu trình duyệt Một cách để giải hai vấn đề sử dụng định dạng JavaScript Object Notation (JSON), mà ngơn ngữ độc lập thể liệu Nó bắt nguồn từ ngơn ngữ JavaScript, xuất từ lâu sử dụng rộng rãi Trong phần này, cho bạn cách để tạo phương thức action trả liệu JSON, làm để xử lý liệu trình duyệt Tip: Trong Chương 27, tơi mơ tả tính Web API, phương pháp thay cho việc tạo dịch vụ Web Thêm JSON để hỗ trợ Controller MVC Framework làm cho việc tạo phương thức action mà tạo JSON liệu trở nên đơn giản Bạn thấy cách tơi thêm phương thức action vào controller People Listing 23-17 Listing 23-17 Một phương thức Action trả liệu JSON tập tin PeopleController.cs 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 = "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(); } private IEnumerable GetData(string selectedRole) { IEnumerable data = personData; if (selectedRole != "All") { Role selected = (Role)Enum.Parse(typeof(Role), selectedRole); data = personData.Where(p => p.Role == selected); } return data; } public JsonResult GetPeopleDataJson(string selectedRole = "All") { IEnumerable data = GetData(selectedRole); return Json(data, JsonRequestBehavior.AllowGet); } public PartialViewResult GetPeopleData(string selectedRole = "All") { return PartialView(GetData(selectedRole)); } public ActionResult GetPeople(string selectedRole = "All") { return View((object)selectedRole); } } } Vì muốn biểu diễn liệu hai định dạng khác (HTML JSON) nên tái cấu controller để có phương pháp GetData chung (và riêng) có trách nhiệm thực việc lọc Tơi thêm phương thức action có tên gọi GetPeopleDataJson trả đối tượng JsonResult Đây kiểu đặc biệt ActionResult để nói với view engine muốn trả lại liệu kiểu JSON cho client khơng phải HTML (Bạn tìm hiểu thêm lớp ActionResult vai trò MVC Framework Chương 17.) Tơi tạo JsonResult cách gọi phương pháp JSON phương thức action, truyền vào liệu mà muốn chuyển đổi sang định dạng JSON: return Json(data, JsonRequestBehavior.AllowGet); Trong trường hợp này, truyền vào giá trị AllowGet từ Enumeration JsonRequestBehavior Theo mặc định, liệu JSON gửi để đáp ứng với yêu cầu POST, cách truyền giá trị tham số cho phương pháp JSON, tơi nói với MVC Framework trả lời yêu cầu GET Caution: Bạn nên sử dụng JsonRequestBehavior.AllowGet liệu bạn trả là private Do vấn đề an ninh nhiều trình duyệt Web, bên thứ ba chặn liệu JSON mà bạn trả lại để trả lời yêu cầu GET, lý mặc định JsonResult không trả lời yêu cầu GET Trong hầu hết trường hợp, để thay bạn sử dụng yêu cầu POST để lấy liệu JSON tránh vấn đề Để biết thêm thông tin, xem link: http://haacked.com/archive/2009/06/25/Json-hijacking.aspx Xử lý Json trình duyệt Để xử lý JSON mà nhận từ máy chủ ứng dụng MVC Framework, định nghĩa chức JavaScript sử dụng thuộc tính callback onSuccess lớp AjaxOptions Trong Listing 23-18, bạn nhìn thấy cách cập nhật tập tin view GetPeople.cshtml để loại bỏ handler function mà định nghĩa phần cuối sử dụng callback onSuccess để xử lý liệu JSON Listing 23-18 Làm việc với liệu JSON tập tin GetPeople.cshtml @using HelperMethods.Models @model string @{ ViewBag.Title = "GetPeople"; Layout = "/Views/Shared/_Layout.cshtml"; AjaxOptions ajaxOpts = new AjaxOptions { UpdateTargetId = "tableBody", Url = Url.Action("GetPeopleData"), LoadingElementId = "loading", LoadingElementDuration = 1000, Confirm = "Do you wish to request new data?" }; } function processData(data) { var target = $("#tableBody"); target.empty(); for (var i = 0; i < data.length; i++) { var person = data[i]; target.append("" + person.FirstName + "" + person.LastName + "" + person.Role + " "); } } Get PeopleLoading Data
First Last Role @Html.Action("GetPeopleData", new { selectedRole = Model }) @using (Ajax.BeginForm(ajaxOpts)) { @Html.DropDownList("selectedRole", new SelectList( new[] { "All" }.Concat(Enum.GetNames(typeof(Role))))) Submit } @foreach (string role in Enum.GetNames(typeof(Role))) { @Ajax.ActionLink(role, "GetPeople", new { selectedRole = role }, new AjaxOptions { Url = Url.Action("GetPeopleDataJson", new { selectedRole = role }), OnSuccess = "processData" }) } Tơi định nghĩa function processData mớicó chứa vài mã code jQuery để sử lý đối tượng Json sử dụng chúng để tạo thẻ để đưa vào Tip Mặc dù tơi thích jQuery tơi khơng sâu vào jQuery sách riêng đề tài Nếu bạn muốn tìm hiểu thêm jQuery bạn tìm đọc jQuery Pro 2.0 (được xuất Apress năm 2013) Chú ý tơi xố giá trị cho thuộc tính UpdateTargetId đối tượng AjaxOptions mà tơi tạo để dùng cho liên kết Nếu bạn quên làm chuyện này, tính unobtrusive Ajax cố gắng xử lý liệu JSON mà lấy từ máy chủ dạng HTML Điều thường xảy nội dung phần tử mục tiêu bị xóa, khơng thay liệu Bạn thấy kết việc chuyển đổi sang JSON cách khởi động ứng dụng, điều hướng đến / People / GetPeople URL, nhấp vào liên kết Như hình 23-9 cho thấy, không nhận kết Đặc biệt, thông tin hiển thị cột Role bảng khơng xác Tơi giải thích lý điều xảy cho bạn thấy làm để làm phần Chuẩn bị liệu cho Encoding Khi gọi phương thức JSON từ phương thức hành động GetPeopleDataJson, để MVC Framework tự hiểu làm để mã hóa đối tượng People định dạng JSON MVC Framework khơng biết chút kiểu model ứng dụng Do đó, cố gắng để đốn cần phải làm Dưới cách MVC Framework thể đối tượng People JSON: {"PersonId":0,"FirstName":"Adam","LastName":"Freeman", "BirthDate":"\/Date(62135596800000)\/","HomeAddress":null,"IsApproved":false,"Role":0} Nhìn lộn xộn, thật thơng minh đưa kết gần với mà tơi cần Trước tiên, tất thuộc tính định nghĩa lớp Person thể JSON, không gán giá trị cho vài thể controller People Trong vài trường hợp, giá trị mặc định cho kiểu sử dụng (ví dụ false sử dụng cho IsApproved), có giá trị null sử dụng (chẳng hạn cho HomeAddress) Một số giá trị chuyển đổi thành dạng dễ dàng bên dịch JavaScript, chẳng hạn thuộc tính BirthDate, khác khơng xử lý, chẳng hạn sử dụng cho thuộc tính Role thay Admin VIEW DỮ LIỆU JSON Thật hữu ích xem liệu JSON mà phương thức action bạn trả cách dễ để làm điều nhập vào URL mà đích action vào trình duyệt: http://localhost:13949/People/GetPeopleDataJson?selectedRole=Guest Bạn làm việc nhiều trình duyệt, hầu hết buộc bạn phải lưu mở tập tin văn trước bạn xem nội dung JSON Tơi thích sử dụng trình duyệt Google Chrome cho việc cách tiện lơi để hiển thị liệu JSON cửa sổ trình duyệt chính, khiến cho q trình nhanh có nghĩa bạn khơng kết thúc với tá cửa sổ tập tin text Tôi đề nghị Fiddler (www.fiddler2.com), mà Web proxy debug tuyệt vời cho phép bạn đào sâu vào chi tiết liệu gửi trình duyệt máy chủ MVC Framework cố gắng, tơi nhận thuộc tính mà tơi khơng sử dụng giá trị Role cách thực có ích Đây tình điển hình dựa mã hóa JSON mặc định, luôn yệu cầu vài chuẩn bị cho liệu bạn muốn gửi cho client Trong Listing 23-19, bạn thấy cách tơi chỉnh sửa phương thức hành động GetPeopleDataJson controller People để chuẩn bị liệu mà truyền vào cho phương thức JSON Listing 23-19 Chuẩn bị đối tượng liệu cho JSON Encoding tập tin PeopleController.cs public JsonResult GetPeopleDataJson(string selectedRole = "All") { var data = GetData(selectedRole).Select(p => new { FirstName = p.FirstName, LastName = p.LastName, Role = Enum.GetName(typeof(Role), p.Role) }); return Json(data, JsonRequestBehavior.AllowGet); } Tôi sử dụng LINQ để tạo chuỗi đối tượng mà chứa thuộc tính FirstName LastName từ đối tượng People, với chuỗi đại diện cho giá trị Role Tác dụng thay đổi nhận liệu JSON mà chứa thuộc tính mà tơi muốn, thể mã jQuery hữu ích hơn: {"FirstName":"Adam","LastName":"Freeman","Role":"Admin"} Figure 23-10 thay đổi kết hiển thị trình duyệt Tất nhiên, bạn khơng phủ nhận thuộc tính khơng sử dụng khơng gửi bạn thấy cột Role chứa giá trị Tip bạn cần phải xóa liệu duyệt web để thấy thay đổi ví dụ Dò tìm yêu cầu Ajax phương thức Action Controller People có hai phương thức action tơi hỗ trợ yêu cầu cho liệu HTML JSON Đây thường cách tạo controllers, tơi thích phương pháp action ngắn đơn giản, bạn không cần phải làm theo cách MVC Framework cung cấp cách đơn giản để dò tìm u cầu Ajax, điều có nghĩa bạn tạo phương thức hành động để xử lý liệu đa định dạng Trong Listing 23-20, bạn thấy cách tơi tái cấu controller Person để chứa phương thức action để xử lý JSON HTML Listing 23-20 Tạo phương thức action tập tin PersonController.cs 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 = "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 ActionResult GetPeopleData(string selectedRole = "All") { IEnumerable 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); } } public ActionResult GetPeople(string selectedRole = "All") { return View((object)selectedRole); } } } Tôi sử dụng phương thức Request.IsAjaxRequest để dò tìm u cầu Ajax cung cấp định dạng JSON kết true Có vài hạn chế mà bạn nên biết trước làm theo phương pháp Trước tiên, phương thức IsAjaxRequest trả true trình duyệt bao gồm X-request- với header request thiết lập giá trị cho XMLHttpRequest Đây quy ước sử dụng rộng rãi, khơng phải phổ biến bạn nên xem xét liệu người dùng bạn có khả thực u cầu đòi hỏi liệu JSON khơng cần pải thiết lập header hay không Hạn chế thứ hai giả định tất yêu cầu Ajax đòi hỏi liệu JSON Ứng dụng bạn hoạt động tốt cách tách riêng cách mà yêu cầu thực cho định dạng liệu mà client tìm kiếm Đây phương pháp ưa thích tơi lý mà hướng tới định nghĩa phương thức action riêng biệt cho định dạng liệu Tôi cần phải thực hai thay đổi view GetPeople.cshtml để hỗ trợ phương thức hành động, Liệt kê 23-21 Listing 23-21 Hỗ trợ phương pháp Action tập tin GetPeople.cshtml @using HelperMethods.Models @model string @{ ViewBag.Title = "GetPeople"; Layout = "/Views/Shared/_Layout.cshtml"; AjaxOptions ajaxOpts = new AjaxOptions { Url = Url.Action("GetPeopleData"), LoadingElementId = "loading", LoadingElementDuration = 1000, OnSuccess = "processData" }; } function processData(data) { var target = $("#tableBody"); target.empty(); for (var i = 0; i < data.length; i++) { var person = data[i]; target.append("" + person.FirstName + "" + person.LastName + "" + person.Role + ""); } } Get PeopleLoading Data
First Last Role @Html.Action("GetPeopleData", new { selectedRole = Model }) @using (Ajax.BeginForm(ajaxOpts)) { @Html.DropDownList("selectedRole", new SelectList( new[] { "All" }.Concat(Enum.GetNames(typeof(Role))))) Submit } @foreach (string role in Enum.GetNames(typeof(Role))) { @Ajax.ActionLink(role, "GetPeople", new { selectedRole = role }, new AjaxOptions { Url = Url.Action("GetPeopleData", new { selectedRole = role }), OnSuccess = "processData" }) } Sự thay đổi đối tượng AjaxOptions tơi sử dụng cho form Ajax Bởi tơi tiếp tục nhận đoạn HTML thông qua yêu cầu Ajax, phải sử dụng chức processData để xử lý JSON phản hồi từ máy chủ mà tạo cho liên kết Ajax Sự thay đổi thứ hai giá trị thuộc tính Urlcho đối tượng AjaxOptions đả dùng để tạo liên kết Các action GetPeopleDataJson khơng tồn tơi dùng action GetPeopleData để thay Tóm tắt Trong chương này, tơi xem xét tính unobtrusive Ajax MVC Framework, lợi dụng chức thư viện jQuery cách đơn giản tao nhã mà không cần thêm nhiều code vào view Nhưng tơi thích làm việc với JSON, có nghĩa Tơi thường cần chức JavaScript nhỏ sử dụng jQuery để xử lý liệu tạo thẻ HTML cần Trong chương tiếp theo, xem xét khía cạnh thú vị hữu ích MVC Framework: model binding ... phương thức action mà tạo JSON liệu trở nên đơn giản Bạn thấy cách thêm phương thức action vào controller People Listing 23- 17 Listing 23- 17 Một phương thức Action trả liệu JSON tập tin PeopleController.cs... thuộc tính mơ tả Bảng 23- 4 Table 23- 4 Các thuộc tính AjaxOptions Callback Từng thuộc tính AjaxOptions callback có liên quan đến kiện Ajax hỗ trợ thư viện jQuery Trong Listing 23- 16, bạn nhìn thấy... chủ gửi yếu tố HTML với liệu) hạn chế thực với liệu trình duyệt Một cách để giải hai vấn đề sử dụng định dạng JavaScript Object Notation (JSON), mà ngôn ngữ độc lập thể liệu Nó bắt nguồn từ ngơn