Formcollection trong MVC là gì
bởi Bạch Ngọc Toàn vào 13/08/2019. Lượt xem: 29,748 Show
Trong cơ chế Model Binding của ASP.NET Core chúng ta sẽ học cách làm sao để truyền dữ liệu từ View lên Controller. Chúng ta cũng sẽ tìm hiểu về Model Binding và cơ chế hoạt động của nó. ASP.NET Core cho phép chúng ta bind dữ liệu từ nhiều nguồn khác nhau như HTML Form sử dụng [FromForm], từ giá trị route [FromRoute], từ query string [FromQuery], từ body của request [FromBody] và từ Header của request [FromHeader]. Một số bài hướng dẫn trước đây có thể tham khảo:
Model Binding là gì?Model Binding là cơ chế map dữ liệu được gửi qua HTTP Request vào các tham số của action method trong Controller. HTTP Request có thể chứa dữ liệu từ nhiều định dạng. Dữ liệu có thể chứa trong HTML Form. Nó có thể là một phần của route value hoặc trên query string hay có thể là một body của request. Cơ chế ASP.NET Core model binding cho phép chúng ta dễ dàng bind các giá trị này vào các tham số của action method. Các tham số này có thể là kiểu nguyên thủy hoặc kiểu đối tượng phức tạp. Lấy dữ liệu từ Form Data trong ControllerTrong bài Tag Helper, chúng ta đã tạo một form cơ bản cho phép nhận một đối tượng Product. Khi người dùng click nút Submit thì dữ liệu sẽ được post lên phương thức Create trên Controller. Trong project đó chúng ta cũng tạo một ProductEditModel class chứa chi tiết của sản phẩm cần được tạo hoặc chỉnh sửa: public class ProductEditModel { public int ID{ get; set; } public string Name { get; set; } public decimal Rate { get; set; } public int Rating { get; set; } }Một form được tạo chứa 3 field: Name, Rate và Rating: Action method Create trong HomeController: [HttpPost] public IActionResult Create(ProductEditModel model) { string message = ""; if (ModelState.IsValid) { message = "product " + model.Name + " created successfully" ; } else { message = "Failed to create the product. Please try again"; } return Content(message); }Một submit của form trên, các giá trị trong form sẽ tự động được map vào đối tượng ProductEditModel trong Action method của controller: public IActionResult Create(ProductEditModel model)Cơ chế này tự động xảy ra đằng sau được gọi là Model Binding. Model Binder sẽ tìm các trường tương ứng giữa tham số ProductEditModel với trường trong form, route value hoặc query string... Cơ chế Model Binding làm việc như thế nào?Hình dưới đây minh họa cơ chế làm việc của Model binding: Khi người dùng click vào nút Submit thì một request Post được gửi lên server với Form Data, QueryString, Route Parameter...MVCRouteHandler của Routing Engine sẽ xử lý request đến và có trách nhiệm gọi action method tương ứng. Model Bindler sẽ được kích hoạt trước khi action method được gọi. Nó tìm dữ liệu thỏa mãn trong form data, querys tring và request parameter trong HTTP Request. Sau đso nó sẽ binding các giá trị vào tham số của action method qua tên. Ví dụ, trường "name" trong form sẽ được map vào thuộc tính "Name" trong ProductEditModel. Rate trong form sẽ được map vào thuộc tính Rate... Để Model binding làm việc đúng:
Model BinderModel Binder có trách nhiệm gán dữ liệu vào các tham số của action method. Model Binder được tạo mởi model binder provider. Model binder phải được implement inteface IModelBinderProvider. Nghĩa là bạn có thể tạo một Model Binder của riêng mình hoặc mở rộng nó bằng cách triển khai inteface IModelBinderProvider. Custom model binder phải được đăng ký trong ModelBinderProviders trong Startup.cs. services.AddMvc(options => { options.ModelBinderProviders.Add(new CustomModelBinderProvider()); });ModelStateNếu Model binder không thành công trong việc bind dữ liệu từ Request vào thuộc tính model tương ứng, nó sẽ không đưa ra bất cứ thông báo lỗi nào. Nhưng nó sẽ update đối tượng ModelState với danh sách lỗi và set thuộc tính IsValid là false. Vì thế kiểm tra ModelState.IsValid sẽ cho chúng ta thấy quá trình binding có thành công hay không. Ví dụ: Trong ví dụ trên khi click nút submit mà không nhập bất cứ dữ liệu gì trên form thì kết quả sẽ ra validate thất bại và vì thế ModelState.IsValid sẽ là false. Nếu không dùng model binding thì sao?Trước khi chúng ta tìm hiểu sâu hơn về Model binding, chúng ta cần hiểu nếu không có model binding thì chúng ta sẽ truy cập đến dữ liệu từ request kiểu gì? Xem lại code mà chúng ta đã tạo trong phần trước. Thêm mới action method NoModelBinding: [HttpPost] public IActionResult NoModelBinding() { ProductEditModel model = new ProductEditModel(); string message = ""; model.Name = Request.Form["Name"].ToString(); model.Rate = Convert.ToDecimal( Request.Form["Rate"]); model.Rating =Convert.ToInt32( Request.Form["Rateing"]); message = "product " + model.Name + " created successfully"; return Content(message); }Và thay đổi thành: Form có tên trường là "name". Chúng ta cũng gửi "name=test" qua query string đến controller action: Chú ý là chúng ta đang gọi controller action bằng cách sử dụng "test" như là giá trị route: |