1. Trang chủ
  2. » Giáo Dục - Đào Tạo

24 chuong 24 tủ tài liệu bách khoa

38 52 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Nội dung

Chương 24 Model Binding Model binding trình việc tạo đối tượng NET sử dụng liệu gửi trình duyệt yêu cầu HTTP Tơi dựa vào quy trình model binding lần tơi định nghĩa phương thức action có tham số Tham số phương thức action tạo thông qua model binding từ liệu yêu cầu Trong chương này, cho bạn thấy cách hệ thống model binding làm việc minh họa kỹ thuật cần thiết để tùy chỉnh để khai thác nhiều lợi ích sử dụng Table 24-1: tóm tắt nội dung chương Chuẩn bị Project minh họa Tôi tạo project Visual Studio gọi MvcModels không sử dụng template lựa chọn tùy chọn để bao gồm thư mục core MVC references Tôi sử dụng lớp model mà bạn thấy chương trước, tạo tập tin lớp gọi Person.cs thư mục Models đảm bảo nội dung phù hợp với Bảng listing 24-1 Listing 24-1 Nội dung tập tin the Person.cs using System; namespace MvcModels.Models { public class Person { public int PersonId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public DateTime BirthDate { get; set; } public Address HomeAddress { get; set; } public bool IsApproved { get; set; } public Role Role { get; set; } } public class Address { public string Line1 { get; set; } public string Line2 { get; set; } public string City { get; set; } public string PostalCode { get; set; } public string Country { get; set; } } public enum Role { Admin, User, Guest } } Tôi định nghĩa controller Home, Listing 24-2 Controller định nghĩa tập hợp đối tượng Person mẫu định nghĩa hành động Index, cho phép để chọn người giá trị thực tính PersonId Listing 24-2 Nội dung tập tin HomeController.cs using System.Linq; using System.Web.Mvc; using MvcModels.Models; namespace MvcModels.Controllers { public class HomeController : Controller { private Person[] personData = { new Person {PersonId = 1, FirstName = "Adam", LastName = "Freeman", Role = Role.Admin}, new Person {PersonId = 2, FirstName = "Jacqui", LastName = "Griffyth", Role = Role.User}, new Person {PersonId = 3, FirstName = "John", LastName = "Smith", Role = Role.User}, new Person {PersonId = 4, FirstName = "Anne", LastName = "Jones", Role = Role.Guest} }; public ActionResult Index(int id) { Person dataItem = personData.Where(p => p.PersonId == id).First(); return View(dataItem); } } } Tôi tạo tập tin View /Views/Home/Index.cshtml để hỗ trợ phương thức action Bạn xem nội dung tập tin Listing 24-3 Tôi sử dụng mẫu @Html.DisplayFor để hiển thị số giá trị thuộc tính view model Person Listing 24-3 Nội dung tập tin /Views/Home/Index.cshtml @model MvcModels.Models.Person @{ ViewBag.Title = "Index"; Layout = "¡«/Views/Shared/_Layout.cshtml"; }< h2>Person ID:@Html.DisplayFor(m => m.PersonId) First Name:@Html.DisplayFor(m => m.FirstName) Last Name:@Html.DisplayFor(m => m.LastName) Role:@Html.DisplayFor(m => m.Role) Cuối cùng, tạo thư mục Views /Shared thêm layout gọi _Layout.cshtml, nội dung nhìn thấy Listing 24-4 Listing 24-4 Nội dung tập tin _Layout.cshtml @ViewBag.Title label { display: inline-block; width: 100px; font-weight: bold; margin: 5px; } form label { float: left; } input.text-box { float: left; margin: 5px; } button[type=submit] { margin-top: 5px; float: left; clear: left; } form div { clear: both; } @RenderBody() Hiểu Model Binding Model binding cầu nối tao nhã yêu cầu HTTP phương pháp C # mà định nghĩa action Hầu hết ứng dụng MVC Framework dựa vào mô hình liên kết với chừng mực đó, bao gồm ứng dụng ví dụ đơn giản mà tơi tạo phần trước Để xem model binding làm việc, khởi động ứng dụng điều hướng đến / Home / Index / Kết minh họa hình 24-1 URL giá trị thuộc tính PersonId đối tượng Person mà tơi muốn xem: /Home/Index/1 MVC Framework biên dịch phần URL sử dụng đối số gọi phương thức Index lớp controller home để phục vụ yêu cầu public ActionResult Index(int id) { Quá trình mà phân đoạn URL chuyển đổi thành tham số int phương thức ví dụ model binding Trong phần tiếp theo, cho bạn trình mà minh họa đơn giản khởi tạo, sau chuyển sang giải thích số model binding tính phức tạp Q trình dẫn đến model binding bắt đầu yêu cầu nhận xử lý công cụ định tuyến Tôi khơng thay đổi cấu hình định tuyến cho ứng dụng ví dụ, dịnh tuyến mặc định mà Visual Studio thêm vào tập tin /App_Start/RouteConfig.cs sử dụng để xử lý yêu cầu Như lời nhắc nhở, bạn xem tuyến đường mặc định Listing 24-5 Listing 24-5 Nội dung tập tin RouteConfig.cs using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace MvcModels { public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } } } Tôi mô tả cách tuyến đường định nghĩa cách thức hoạt động chi tiết Chương 15 16, tơi khơng lặp lại thơng tin Đối với q trình model binding , phần quan trọng biến phân đoạn tùy chọn id Khi chuyển đến / Home / Index / URL, đoạn cuối URL, xác định đối tượng người mà tơi muốn lấy thông tin, gán cho biến id định tuyến The Invoker action, mà giới thiệu chương 17, sử dụng thơng tin định tuyến để tìm phương thức action Index yêu cầu để phục vụ u cầu, khơng thể gọi phương thức Index có giá trị cho đối số phương thức The Invoker action mặc định, ControllerActionInvoker, (được giới thiệu chương 17), dựa vào model bindersh để tạo đối tượng liệu yêu cầu để gọi action Model binders xác định interface IModelBinder, thể Listing 24-6 Tôi trở lại với giao diện sau chương cho bạn cách để tạo mmodel binders tùy chỉnh Listing 24-6 Interface IModelBinder MVC Framework namespace System.Web.Mvc { public interface IModelBinder { object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext); } } Có thể có nhiều model binders ứng dụng MVC, model binders chịu trách nhiệm ràng buộc nhiều loại model Khi invoker action cần gọi phương thức action, xem xét thơng số mà phương thức định nghĩa tìm kiếm model binders chịu trách nhiệm cho loại Ví dụ phần này, invoker hành động kiểm tra phương thức Index thấy có tham số int Sau xác định vị trí binder chịu trách nhiệm giá trị int gọi phương thức BindModel Các model binder chịu trách nhiệm cung cấp giá trị int sử dụng để gọi phương thức Index Điều thường có nghĩa chuyển đổi số phần tử liệu yêu cầu (như form giá trị chuỗi truy vấn), MVC Framework không đặt giới hạn thu thập liệu Tơi cho bạn số ví dụ tùy chỉnh binder chương Tôi giới thiệu bạn số tính lớp ModelBindingContext, truyền cho phương thức IModelBinder.BindModel Sử dụng Model Binder mặc định Mặc dù ứng dụng định nghĩa model binders tùy chỉnh, hầu hết dựa vào tích hợp lớp binder, DefaultModelBinder Đây binder sử dụng invoker action khơng thể tìm thấy binder tùy chỉnh để ràng buộc dạng Theo mặc định, mơ hình bìa tìm kiếm bốn địa điểm, thể Bảng 24-2, cho liệu phù hợp với tên tham số bị ràng buộc Table 24-2 Thứ tự mà lớp DefaultModelBinder tìm kiếm liệu đối số Các vị trí tìm Ví dụ, ví dụ đơn giản tơi, DefaultModelBinder tìm kiếm giá trị cho tham số id sau: Request.Form["id"] RouteData.Values["id"] Request.QueryString["id"] Request.Files["id"] Việc tìm kiếm ngừng lại giá trị tìm thấy Trong ví dụ, form khơng tìm kiếm hồn tồn biến định tuyết tìm thấy với định danh Điều có nghĩa chuỗi truy vấn tên tập tin tải lên hồn tồn khơng tìm Tip: Khi dựa model binder mặc định, điều quan trọng tham số cho phương thức action bạn khớp với thuộc tính liệu bạn tìm kiếm Ứng dụng ví dụ tơi hoạt động tên tham số phương thức action tương ứng với tên biến định tuyến Nếu đặt tên cho tham số phương thức action PersonId, model binder mặc định định vị giá trị liệu phù hợp yêu cầu thất bại Ràng buộc kiểu đơn giản Khi xử lý với loại tham số đơn giản, DefaultModelBinder tìm cách để chuyển đổi chuỗi giá trị thu từ liệu yêu cầu thành kiểu tham số sử dụng lớp System.ComponentModel.TypeDescriptor Nếu giá trị chuyển đổi (chẳng hạn như, cung cấp giá trị kiểu chuỗi apple cho tham số mà đòi hỏi giá trị int), DefaultModelBinder khơng thể liên kết với model Bạn thấy vấn đề mà việc gây cách khởi động ứng dụng ví dụ điều hướng đến URL / Home / Index / apple Hình 24-2 minh họa phản hồi từ máy chủ Model binder mặc định binder cứng đầu Nó thấy giá trị int cần thiết cố gắng để chuyển đổi giá trị mà cung cấp URL, apple, thành kiểu int, mà nguyên nhân lỗi hiển thị hình Tơi làm cho việc dễ dàng cho model binder cách sử dụng loại nullable, để cung cấp cho model binder phương án dự phòng Bạn thấy cách tơi áp dụng loại nullable vào action Index Listing 24-7 Listing 24-7 Nội dung tập tin HomeController.cs public ActionResult Index(int? id) { Person dataItem = personData.Where(p => p.PersonId == id).First(); return View(dataItem); } Nếu bạn khởi động lại ứng dụng điều hướng tới /Home/Index/apple bạn thấy thay đổi thay giải vấ để: Bất kể lúc model binder khơng thể tìm giá trị phù hợp cho tham số id, giá trị mặc định sử dụng thay vào Do chọn đối tượng Person có giá trị personID Tip: Lưu ý giải vấn đề giá trị khơng phải số cho mơ hình chất kết dính, mà tơi lấy giá trị int mà khơng có đối tượng Person hợp lệ định nghĩa controller Home Chẳng hạn, model binder vui vẻ chuyển đổi phân đoạn cuối URL / Home / Index / -1 / Home / Index / 500 thành giá trị int Điều cho phép phương thức action gọi phương thức Index với giá trị thực, dẫn đến lỗi tơi khơng thực kiểm tra bổ sung controller Tôi khuyên bạn nên ý đến phạm vi giá trị tham số phương thức action bạn nhận kiểm nghiệm thích hợp CÚ PHÁP CHUYỂN ĐỔI VÙNG MIỀN NHẠY CẢM Lớp DefaultModelBinder sử dụng cài đặt đặc tả vùng miền để thực chuyển đổi kiểu từ phần khác liệu request Các giá trị thu thập từ URL (bao gồm định tuyến liệu chuỗi truy vấn) chuyển đổi sử dụng chế độ chuyển đổi culture-insensitive giá trị từ liệu form chuyển đổi sử dụng chế độ culture into account Vấn đề phổ biến mà điều gây liên quan đến giá trị DateTime Giá trị ngày Culture-insensitive kỳ vọng định dạng phổ biến: yyyy-mm-dd Giá trị ngày Form kỳ vọng định dạng theo định máy chủ Điều có nghĩa máy chủ cài đặt với văn hóa Anh kỳ vọng ngày định dạng dd- }< h2>Names @if (Model.Count == 0) { using (Html.BeginForm()) { for (int i = 0; i < 3; i++) { @(i + 1):@Html.TextBox("names") } Submit } } else { foreach (string str in Model) {

@str

} @Html.ActionLink("Back", "Names"); } Tính action Names khơng đổi tơi làm việc với collection thay mảng Ràng buộc Collection kiểu Model tùy chỉnh Tôi ràng buộc riêng thuộc tính dự liệu vào mảng tùy chọn liệu, lớp model AddressSummary Trong Listing 24-25, bạn thấy tơi thêm vào mội phương thức action vào controller Home gọi Address có tham số kiểu collection dựa vào lớp model tùy chỉnh Listing 24-25 Nội dung tập tin HomeController.cs using System.Collections.Generic; using System.Linq; using System.Web.Mvc; using MvcModels.Models; namespace MvcModels.Controllers { public class HomeController : Controller { // other methods and statements omitted for brevity public ActionResult Address(IList addresses) { addresses = addresses ?? new List(); return View(addresses); } } } View mà tạo cho phương thức action /Views/Home/Address.cshtml, bạn thấy Listing 24-26 Listing 24-26 Nội dung tập tin Address.cshtml tập tin @using MvcModels.Models @model IList @{ ViewBag.Title = "Address"; Layout = "∼/Views/Shared/_Layout.cshtml"; }< h2>Addresses @if (Model.Count() == 0) { using (Html.BeginForm()) { for (int i = 0; i < 3; i++) { Address @(i + 1) City:@Html.Editor("[" + i + "].City") Country:@Html.Editor("[" + i + "].Country") } Submit } } else { foreach (AddressSummary str in Model) {

@str.City, @str.Country

} @Html.ActionLink("Back", "Address"); } View trả vể khơng có item model collection Form bao gồm cặp thuộc tính mơ tả name prefixed với số mảng sau: Address 1 City: Country: Address 2 City: Country: Khi Form submit, model binder mặc định nhận cần phải tạo đối tượng collection AddressSummary sử dụng số mảng để prefix thuộc tính mô tả name để thu thập giá trị cho thuộc tính đối tượng Các thuộc tính prefix [0] sử dụng cho đối tượng AddressSummary đầu tiên, prefix [1] sử dụng cho đối tượng thứ hai tiếp tục đến hết View Address.cshtml định nghĩa cho ba đối tượng đánh mục hiển thị chúng model collection có chứa item Trước tơi minh họa nó, tơi cần xóa thuộc tính mơ tả Bind lớp model AddressSummary Listing 24-27; không model binder bỏ qua thuộc tính Country Listing 24-27 Nội dung tập tin AddressSummary.cs using System.Web.Mvc; namespace MvcModels.Models { // This attribute has been commented out //[Bind(Include="City")] public class AddressSummary { public string City { get; set; } public string Country { get; set; } } } Bạn thấy cách trình ràng buộc cho đối tượng collection tùy chỉnh làm việc cách khởi động ứng dụng điều hướng đến URL /Home/Address Sử dụng vài thành phố vài quốc gia sau submit để post form đến server Model binder tìm kiếm xử lí giá trị liệu đánh mục sử dụng chúng để tạo đối tượng collection AddressSummary mà sau truyền ngược cho view hiển thị cho bạn hình 24-9 Gọi model binding cách thủ cơng Q trình model binding thực thi tự động phương thức action định nghĩa tham số tơi trực tiếp điều khiển tơi muốn Việc cho phép điều khiển cách rõ ràng cách đối tượng model khởi tạo, chỗ mà giá trị liệu thu thập, cách lỗi chuyển đổi liệu xử lí Listing 24-28 minh họa cách tơi thay đổi phương thức action Address controller Home để gọi trình binding cách thủ cơng Listing 24-28 Nội dung tập tin HomeController.cs using System.Collections.Generic; using System.Linq; using System.Web.Mvc; using MvcModels.Models; namespace MvcModels.Controllers { public class HomeController : Controller { // other methods and statements omitted for brevity public ActionResult Address() { IList addresses = new List(); UpdateModel(addresses); return View(addresses); } } } Phương thức UpdateModel lấy đối tượng model mà vừa định nghĩa tham số cố thu thập giá trị cho thuộc tính public sử dụng q trình binding chuẩn Khi tơi gọi q trình binding cách thủ cơng, tơi ngăn cản q trình ràng buộc liệu đơn Mặc định, binder tìm kiêm nơi: liệu form, liệu định tuyến, chuỗi truy vấn tập tin tải lên Listing 24-29 thể cách hạn chế binder tìm kiếm dử liệ vị trí nhất, trường hợp liệu form Listing 24-29 Nội dung tập tin HomeController.cs public ActionResult Address() { IList addresses = new List(); UpdateModel(addresses, new FormValueProvider(ControllerContext)); return View(addresses); } Phiên phương thức UpdateModel lấy thực thi interface IValueProvider, mà người liệu cho trình ràng buộc Mỗi vị trí bốn vị trí liệu mặc định thề thực thi IValueProvider hình Table 24-3 Mỗi lớp liệt kê bảng 24-3 thâm số khởi tạo ControllerContext mà tơi thu thập thơng qua thuộc tính gọi ControllerContext định nghĩa lớp Controller listing Cách phổ biến để hạn chế nguồn liệu tìm kiếm giá trị form Có mẹo ràng buộc gọn gàng mà sử dụng tơi khơng phải tạo thực thể FormValueProvider Listing 2430 Listing 24-30 Nội dung tập tin HomeController.cs public ActionResult Address(FormCollection formData) { IList addresses = new List(); UpdateModel(addresses, formData); return View(addresses); } Lớp FormCollection thực thi interface IValueProvider định nghĩa phương thức action để lấy tham số kiểu này, model binder cung cấp cho dối tượng mà tơi truyền trực tiếp vào phương thức UpdateMethod Tip: có phiên khác phương thức UpdateMethod rõ prefix để tìm kiếm thuộc tính model chứa trình ràng buộc Giải lỗi ràng buộc Người dùng chắn cung cấp giá trị mà khơng thể bị ràng buộc vào thuộc tính ngày tháng hợp lệ model text giá trị số Khi gọi model binding cách rõ ràng, tơi có trách nhiệm đối phó với lỗi Các model binder lỗi ràng buộc cách ném InvalidOperationException Chi tiết lỗi tìm thấy thơng qua tính ModelState, mà mô tả Chương 25 Nhưng sử dụng phương pháp UpdateModel, phải chuẩn bị để bắt ngoại lệ sử dụng ModelState để thể thông báo lỗi cho người dùng, hiển thị Listing 24-31 Listing 24-31 Nội dung tập tin HomeController.cs public ActionResult Address(FormCollection formData) { IList addresses = new List(); try { UpdateModel(addresses, formData); } catch (InvalidOperationException ex) { // provide feedback to user } return View(addresses); } Như cách tiếp cận thay thế, tơi sử dụng phương thức TryUpdateModel, mà trả true trình model binding thành cơng false có lỗi Listing 24-32 Listing 24-32 Nội dung tập tin HomeController.cs public ActionResult Address(FormCollection formData) { IList addresses = new List(); if (TryUpdateModel(addresses, formData)) { // proceed as normal } else { // provide feedback to user } return View(addresses); } Lý để ưu tiên TryUpdateModel UpdateModel bạn khơng thích bắt xử lý trường hợp ngoại lệ Khơng có khác biệt chức mơ hình q trình ràng buộc Tip: Khi model binding gọi tự động, lỗi ràng buộc không thông báo với trường hợp ngoại lệ Thay vào đó, bạn phải kiểm tra kết thơng qua thuộc tính ModelState.IsValid Tơi giải thích ModelState Chương 25 Tùy chỉnh hệ thống Model Binding Tôi cho bạn mơ hình mặc định quy trình ràng buộc Như bạn kỳ vọng bây giờ, có số cách khác nhau, hệ thống ràng buộc tùy chỉnh Tơi cho bạn số ví dụ phần sau Tạo Provider tùy chỉnh giá trị Bằng việc xác định Provider tùy chỉnh giá trị, tơi thêm source riêng tơi liệu cho q trình model binding Provider thực thi interface IValueProvider, thể Listing 24-33 Listing 24-33 Nội dung interface IValueProvider namespace System.Web.Mvc { public interface IValueProvider { bool ContainsPrefix(string prefix); ValueProviderResult GetValue(string key); } } Các Phuong thức ContainsPrefix gọi model binder để xác định liệu giá trị Provider giải liệu prefix cho hay không Phương thức GetValue trả giá trị key cho, null provider khơng có liệu phù hợp Tơi thêm thư mục Infrastructure cho ứng dụng ví dụ tạo lớp gọi CountryValueProvider.cs, mà sử dụng để cung cấp giá trị cho thuộc tính Country Bạn xem nội dung tập tin Listing 24-34 Listing 24-34 Nội dung tập tin CountryValueProvider.cs using System.Globalization; using System.Web.Mvc; namespace MvcModels.Infrastructure { public class CountryValueProvider : IValueProvider { public bool ContainsPrefix(string prefix) { return prefix.ToLower().IndexOf("country") > -1; } public ValueProviderResult GetValue(string key) { if (ContainsPrefix(key)) { return new ValueProviderResult("USA", "USA", CultureInfo.InvariantCulture); } else { return null; } } } } Giá trị Provider đáp ứng yêu cầu cho giá trị cho thuộc tính Country ln ln trả giá trị USA Đối với tất yêu cầu khác, trả null, cung cấp liệu Tôi phải trả giá trị liệu kiểu ValueProviderResult Lớp có ba thơng số constructor Đầu tiên liệu mà tơi muốn kết hợp với khóa u cầu Tham số thứ hai phiên giá trị liệu an toàn để hiển thị phần trang HTML.Tham số cuối thơng tin văn hóa có liên quan đến giá trị; Tơi có định InvariantCulture Để đăng giá trị provider cho ứng dụng, cần phải tạo lớp factory mà tạo thực thể provider chúng yêu cầu MVC Framework Các lớp factory phải chiết xuất từ lớp Abstract ValueProviderFactory Listing 24-35 Nội dung tập tin ValueProviderFactory.cs using System.Web.Mvc; namespace MvcModels.Infrastructure { public class CustomValueProviderFactory : ValueProviderFactory { public override IValueProvider GetValueProvider(ControllerContext controllerContext) { return new CountryValueProvider(); } } } Phương pháp GetValueProvider gọi model binder muốn có giá trị cho q trình binding Việc thực thi đơn giản tạo trả thể lớp CountryValueProvider, bạn sử dụng liệu cung cấp thông qua tham số ControllerContext để đáp ứng với loại khác yêu cầu cách tạo provider giá trị khác Tôi cần đăng kí lớp factory với ứng dụng phương thức Application_Start tập tin Global.asax Listing 24-36 Listing 24-36 Nội dung tập tin Global.asax using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; using MvcModels.Infrastructure; namespace MvcModels { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); ValueProviderFactories.Factories.Insert(0, new CustomValueProviderFactory()); } } } Tôi đăng ký lớp factory cách thêm thực thể vào collection ValueProviderFactories.Factories tĩnh Model binder xem xét provider giá trị theo thứ tự, có nghĩa phải sử dụng phương thức Insert để đặt factory tùy chỉnh vị trí sưu tập muốn ưu tiên provider tích hợp Nếu tơi muốn provider tùy chinh fallback sử dụng provider khác khơng thẻ cung cấp giá trị liệu tơi sử dụng phương thức Add để thêm lớp factory vào vị trí cuối collection ValueProviderFactories.Factories.Add(new CustomValueProviderFactory()); Tôi muốn provider giá trị tùy chỉnh sử dụng trước provider khác, sử dụng phương pháp Insert Tôi cần phải chỉnh sửa phương thức action Address trước kiểm tra provider giá trị, model binder không xem xét liệu mẫu cho giá trị thuộc tính model Trong Listing 24-37, bạn nhìn thấy cách tơi tơi xố hạn chế mã nguồn cho giá trị lệnh gọi phương thức TryUpdateModel Listing 24-37 Nội dung tập tin HomeController.cs using System.Collections.Generic; using System.Linq; using System.Web.Mvc; using MvcModels.Models; namespace MvcModels.Controllers { public class HomeController : Controller { // other methods and statements omitted for brevity public ActionResult Address() { IList addresses = new List(); UpdateModel(addresses); return View(addresses); } } } Bạn thấy provider giá trị tùy chỉnh hoạt động bạn khởi động ứng dụng điều hướng đến URL /Home/Address Nhập vào liệu thuộc tính thành phố quốc gia, sau submit Bạn thấy provider giá trị tùy chỉnh có ưu tiên provider tích hợp dùng để tạo giá trị cho thuộc tính Country đối tượng AddressSummary tạo model binder hình 24-10 Tạo model binder tùy chỉnh Tơi ghi đè hàn vi binder mặc cách tạo model binder tùy chỉnh cho loại cụ thể Model binder tùy chỉnh thực thi interface IModelBinder mà đầu chương Để minh họa cách tạo binder tùy chỉnh, thêm lớp AddressSummaryBinder.cs thư mục Infrastructure, bạn thấy nội dung Listing 24-38 Listing 24-38 Nội dung tập tin AddressSummaryBinder.cs using MvcModels.Models; using System.Web.Mvc; namespace MvcModels.Infrastructure { public class AddressSummaryBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { AddressSummary model = (AddressSummary)bindingContext.Model ?? new AddressSummary(); model.City = GetValue(bindingContext, "City"); model.Country = GetValue(bindingContext, "Country"); return model; } private string GetValue(ModelBindingContext context, string name) { name = (context.ModelName == "" ? "" : context.ModelName + ".") + name; ValueProviderResult result = context.ValueProvider.GetValue(name); if (result == null || result.AttemptedValue == "") { return ""; } else { return (string)result.AttemptedValue; } } } } MVC Framework gọi phương thức BindModel muốn thể kiểu model mà binder hỗ trợ Tơi bạn cách ngắn gọn để đăng kí model binder lớp AdreesSummaryBinder sử dụng để tạo thể lớp AddressSummary làm cho code đơn giản (bạn tạo binder tùy chỉnh hỗ trợ đa định dạng tơi thích binder cho kiểu) Tip: Tôi không thực kiểm tra đầu vào model binder này, có nghĩa tơi vơ tình đốn người dùng cung cấp giá trị hợp lệ cho tất thuộc tính Person Tôi thảo luận xác nhận Chương 25, thời điểm này, muốn tập trung vào trình model binding Các tham số phương pháp BindModel đối tượng ControllerContext mà bạn sử dụng để có thơng tin chi tiết yêu cầu đối tượng ModelBindingContext, cung cấp thông tin chi tiết đối tượng model tìm kiếm, truy cập vào phần lại sở model binding ứng dụng MVC Trong Bảng 24-4, mô tả thuộc tính hữu ích xác định lớp ModelBindingContext Model binder tùy chỉnh đơn giản Khi phương thức BindModel gọi, tơi kiểm tra xem thuộc tính Model đối tượng ModelBindingContext có cài đặt hay khơng Nếu cài đặt, đối tượng mà tạo giá trị liệu cho, khơng tơi tạo thực thể lớp AddressSummary Tơi lấy giá trị cho thuộc tính City Country cách gọi phương thức GetValue trả đối tượng AddressSummary Trong phương thức GetValue, sử dụng thực thi interface IValueProvider thu từ thuộc tính ModelBindingContext.ValueProvider để lấy giá trị cho thuộc tính mơ hình đối tượng Thuộc tính ModelName nói với tơi có tiền tố tơi cần phải nối thêm vào tên thuộc tính tơi tìm kiếm Bạn nhớ lại phương thức action cố gắng để tạo collection đối tượng AddressSummary, có nghĩa yếu tố đầu vào riêng có giá trị thuộc tính tên bắt đầu [0] [1] Giá trị tơi tìm kiếm yêu cầu [0] City, [0] Country, tiếp tục Bước cuối cùng, cung cấp giá trị mặc định tơi khơng thể tìm thấy giá trị cho thuộc tính thuộc tính chuỗi rỗng (đó gửi đến máy chủ người dùng không nhập giá trị vào thẻ form) Đăng kí Model Binder tùy chọn Tơi phải đăng ký model binder tùy chọn để ứng dụng MVC hiểu cần phải hỗ trợ kiểu Tôi thực việc phuong thức Application_Start Global.asax, minh họa Listing 24-39 Listing 24-39 Nội dung tập tin Global.asax using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; using MvcModels.Infrastructure; using MvcModels.Models; namespace MvcModels { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); // This statement has been commented out //ValueProviderFactories.Factories.Insert(0, // new CustomValueProviderFactory()); ModelBinders.Binders.Add(typeof(AddressSummary), new AddressSummaryBinder()); } } } Tôi đăng ký binder thông qua phương thức ModelBinders.Binders.Add, truyền vào loại mà binder hỗ trợ thể lớp binder Chú ý tơi xố câu lệnh để đăng ký provider giá trị tùy chỉnh Bạn kiểm tra model binder tùy chỉnh cách bắt đầu ứng dụng, điều hướng đến URL / Home / Address, điền vào vài thẻ cùa form Khi bạn submit form, model binder tùy chỉnh sử dụng để hiển thị tất thuộc tính mà bạn không nhập vào giá trị, thể hình 24-11 Đăng kí Model Binder với thuộc tính mơ tả Bạn đăng ký model binders tùy chỉnh cách thêm vào lớp model thuộc tính mơ tả ModelBinder, có nghĩa bạn khơng cần phải sử dụng tập tin Global.asax Trong Listing 24-40, bạn thấy tơi định AddressSummaryBinder binder cho lớp AddressSummary Listing 24-40 Nội dung tập tin AddressSummary.cs using System.Web.Mvc; using MvcModels.Infrastructure; namespace MvcModels.Models { [ModelBinder(typeof(AddressSummaryBinder))] public class AddressSummary { public string City { get; set; } public string Country { get; set; } } } Tổng kết Trong chương này, giới thiệu cho bạn hoạt động trình model binding, cho bạn thấy làm model binding mặc định hoạt động cách thức triển khai khác nhau, q trình tùy chỉnh Nhiều ứng dụng MVC Framework cần model binder mặc định đủ để xử lý HTML mà phương thức helper tạo Nhưng ứng dụng cao cấp hơn, việc sử dụng model binding tùy chỉnh hữu ích việc tạo đối tượng model cách hiệu cụ thể Trong chương tiếp theo, cho bạn làm để chứng thực đối tượng mơ hình cách thể cho người dùng với lỗi có ý nghĩa liệu khơng hợp lệ nhận ... buộc liệu đơn Mặc định, binder tìm kiêm nơi: liệu form, liệu định tuyến, chuỗi truy vấn tập tin tải lên Listing 24- 29 thể cách tơi hạn chế binder tìm kiếm dử liệ vị trí nhất, trường hợp liệu. .. thực thi concrete( dù tơi tơi thích) Trong Listing 24- 24, bạn thấy cách tơi chỉnh sửa tập tin view Names.cshtml để sử dụng kiểu model Listing 24- 24 Nội dung tập tin Names.cshtml @model IList... mà giá trị liệu thu thập, cách lỗi chuyển đổi liệu xử lí Listing 24- 28 minh họa cách thay đổi phương thức action Address controller Home để gọi trình binding cách thủ công Listing 24- 28 Nội dung

Ngày đăng: 09/11/2019, 07:22

TÀI LIỆU CÙNG NGƯỜI DÙNG

  • Đang cập nhật ...

TÀI LIỆU LIÊN QUAN