Nút mvc onclick javascript

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 liên kết dữ liệu từ nhiều nguồn khác nhau như HTML Form sử dụng [FromForm], từ giá trị tuyến đường [FromRoute], từ chuỗi truy vấn [FromQuery], từ phần thân của yêu cầu [FromBody] và từ Tiêu đề của yêu cầu

Một số bài hướng dẫn trước đây có thể tham khảo

  • Model và ViewModel trong ASP. NET lõi MVC
  • Truyền dữ liệu từ Controller sang View trong ASP. NET lõi
  • Xây dựng HTML Form trong ASP. NET lõi
  • Strongly Typed View trong ASP. NET lõi
  • Tag Helpers trong ASP. NET lõi MVC

Model Binding là gì?

Model Binding là cơ chế map data được gửi qua HTTP Request vào các tham số của phương thức hành động trong Controller. Yêu cầu HTTP có thể chứa dữ liệu từ nhiều định dạng. Dữ liệu có thể chứa trong Biểu mẫu HTML. Nó có thể là một phần của giá trị tuyến đường hoặc trên chuỗi truy vấn hoặc có thể là một phần của yêu cầu

ASP mode. NET Core model binding cho phép chúng ta dễ dàng ràng buộc các giá trị này vào tham số của phương thức hành động. 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 Controller

Trong bài Tag Helper, chúng ta đã tạo một biểu mẫu cơ bản cho phép nhận một đối tượng Sản phẩm. Khi người dùng nhấp vào nút Gửi, dữ liệu sẽ được đăng lên phương thức Tạo trên Bộ điều khiển. Trong dự án đó chúng ta cũng tạo ra một lớp ProductEditModel chứa thông tin chi tiết của sản phẩm cần 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 biểu mẫu được tạo bao gồm 3 trường. Tên, Tỷ lệ và Đánh giá

Phương thức hành động Tạo 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 lần gửi biểu mẫu trên, các giá trị trong biểu mẫu sẽ tự động được ánh xạ vào đối tượng ProductEditModel trong Phương thức hành động của bộ điều khiển

public IActionResult Create(ProductEditModel model)

Cơ chế này tự nhiên xảy ra phía 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 biểu mẫu, giá trị định tuyến hoặc chuỗi truy vấn

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

 

Nút mvc onclick javascript

Khi người dùng click vào nút Submit thì một yêu cầu Post được gửi lên server với Form Data, QueryString, Route Parameter. MVCRouteHandler của Routing Engine sẽ xử lý yêu cầu đến và có nhiệm vụ gọi phương thức hành động tương ứng. Model Bindler sẽ được kích hoạt trước khi phương thức hành động được gọi. Nó tìm dữ liệu đáp ứng trong dữ liệu biểu mẫu, truy vấn tring và tham số yêu cầu trong Yêu cầu HTTP. Sau đó nó sẽ ràng buộc các giá trị tham số của phương thức hành động thông qua tên

Ví dụ, trường "tên" trong biểu mẫu sẽ được ánh xạ vào thuộc tính "Tên" trong ProductEditModel. Rate in form will be ánh xạ vào thuộc tính Rate

 

Nút mvc onclick javascript

To model binding doing true

  • Tên Thuộc tính phải khớp với Dữ liệu Yêu cầu
  • Cấc thuộc tính must set public set

chất kết dính mô hình

Model Binder có nhiệm vụ gán dữ liệu vào các tham số của phương thức hành động. Model Binder được tạo ra để mở nhà cung cấp chất kết dính mô hình. Model binder must be implement inteface IModelBinderProvider. Nghĩa là bạn có thể tạo Model Binder của riêng mình hoặc mở rộng nó bằng cách khai thác giao diện IModelBinderProvider. Custom model binder must be register in ModelBinderProviders trong Startup. cs

services.AddMvc(options =>
{
    options.ModelBinderProviders.Add(new CustomModelBinderProvider());
});

Mô hìnhNhà nước

If Model binder failed in the bind data from Request on the property model compatible, it will not give a any any report error. Nhưng nó sẽ cập nhật ModelState đối tượng với danh sách lỗi và đặt thuộc tính IsValid là sai

Vì thế kiểm tra ModelState. IsValid sẽ cho chúng ta thấy quá trình ràng buộc có thành công hay không

Ví dụ. Trong ví dụ trên khi nhấp vào nút gửi mà không nhập bất kỳ dữ liệu nào vào biểu mẫu, kết quả sẽ khiến xác thực thất bại và vì thế ModelState. IsValid sẽ là sai

Nếu không sử dụng ràng buộc mô hình 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 dữ liệu từ yêu cầu kiểu gì? . Add new 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);
}

And change to

Truy cập trực tiếp đến chuỗi truy vấn

Tương tự như thế, bạn có thể truy cập các giá trị trên chuỗi truy vấn sử dụng Yêu cầu. Truy vấn. Get the value on query string

Ví dụ, Yêu cầu. Truy vấn["id"]. ToString() return value of id on query string. Use Request. Chuỗi truy vấn. HasValue sẽ cho bạn biết liệu chuỗi truy vấn có giá trị trên URL hiện tại hay không và Yêu cầu. Chuỗi truy vấn. Giá trị sẽ trả về giá trị thô của chuỗi truy vấn

Truy cập trực tiếp đến Tiêu đề yêu cầu

Tương tự như thế, bạn có thể sử dụng Yêu cầu. Tiêu đề để truy cập các giá trị được gửi lên thông qua Tiêu đề HTTP

Truy cập dữ liệu định tuyến

To access to route you must write over the method OnActionExecuting

using Microsoft.AspNetCore.Mvc.Filters;

public override void OnActionExecuting(ActionExecutingContext context)
{
    string id = context.RouteData.Values["id"].ToString();
    base.OnActionExecuting(context);
}

Bạn thấy rằng có rất nhiều mã để lấy giá trị được đăng lên HTTP Request. ASP. NET Core model binding sẽ giúp bạn làm việc này mà sử dụng ít mã hơn

Các nguồn cho Model ràng buộc

Như đã đề cập trước đây, mô hình chất kết dính có thể lấy dữ liệu từ rất nhiều nơi khác nhau. Đây là danh sách các nguồn dữ liệu theo thứ tự mà ràng buộc mô hình sẽ tìm thấy

  • Giá trị biểu mẫu HTML
  • Giá trị tuyến đường
  • Chuỗi truy vấn

Model binder cũng có thể tìm dữ liệu từ các nguồn sau, nhưng chúng ta cần chỉ ra những nguồn nào cần lấy một cách tường minh

  • Nội dung yêu cầu
  • Tiêu đề yêu cầu
  • Dịch vụ

Lấy dữ liệu từ Biểu mẫu và Chuỗi truy vấn

Please try binding action parameter with both form and query string. FormAndQuery method will like after

________số 8

Chú ý rằng action method FormAndQuery có hai tham số name và ProductEditModel

public IActionResult FormAndQuery(string name,ProductEditModel model)

Tiếp theo, chúng ta tạo view FormAndQuery as after


    
    

    
    
    
    
    
0

Biểu mẫu có tên trường là "tên". Chúng ta cũng gửi "name=test" qua chuỗi truy vấn đến hành động của bộ điều khiển

1

Trong ví dụ trên, tham số "tên" xuất hiện 2 lần như một phần của chuỗi truy vấn. Khi biểu mẫu được gửi, tham số "tên" luôn ánh xạ đến trường trong biểu mẫu chứ không phải chuỗi truy vấn. Bởi vì model binder luôn sử dụng thứ tự map data theo thứ tự

  1. Giá trị biểu mẫu
  2. Giá trị tuyến đường
  3. Chuỗi truy vấn

Vì thế các giá trị trong biểu mẫu có tên trường, tên tham số luôn được gán giá trị. Chúng ta có thể thay đổi hành vi này bằng cách bổ sung thuộc tính [FromQuery]. Use [FromQuery] as after

2

Giờ nếu gửi biểu mẫu thì tham số name sẽ lấy giá trị từ chuỗi truy vấn, trong khi ProductEditModel sẽ lấy giá trị từ biểu mẫu

Control Binding Source

Trong ví dụ trước, chúng ta sử dụng [FromQuery] để bắt buộc mô hình chất kết dính thay đổi hành vi mặc định và sử dụng chuỗi truy vấn làm nguồn cho ràng buộc. ASP. NET Core cung cấp cho chúng tôi một số thuộc tính điều khiển và chọn nguồn nào sẽ nhận được khi ràng buộc

  1. [Từ hình thức]
  2. [Từ tuyến đường]
  3. [Truy vấn từ]
  4. [TừBody]
  5. [Từ tiêu đề]
  6. [TừDịch vụ]

[Từ hình thức]

[FromForm] ép model binder bind tham số vào các trường của HTML Form

3

[Từ tuyến đường]

[FromRoute] ép model binder bind tham số vào route data từ request.  

Ví dụ. Tạo một phương thức hành động FromRoute, cho phép một giá trị id và ProductEditModel. Chúng ta có 2 tham số id. MVC mặc định sẽ có tham số Id qua route và nó là tùy chọn. ProductEditModel also have id thuộc tính

4

Create view FromRoute

5

Chú ý là chúng ta đang gọi hành động của bộ điều khiển bằng cách sử dụng "kiểm tra" như là giá trị tuyến đường

6

Time when submit form, number id always map to id from form instead of route value. Giờ hãy mở HomeController ra và áp dụng [FromRoute] trên tham số id

7

Khi gửi biểu mẫu, id sẽ được nhận là "kiểm tra"

Ràng buộc chuỗi truy vấn sử dụng [FromQuery]

[FromQuery] ép model binder bind value vào tham số từ value query from query string

Ràng buộc đến nội dung yêu cầu sử dụng [FromBody]

[FromBody] ép model binder bind data from request body. Formatter will choose based on content-type of request. Dữ liệu trong phần thân yêu cầu có nhiều định dạng khác nhau như JSON, XML. Model binder sẽ tìm thuộc tính content-type trên header và select formatter để chuyển dữ liệu về kiểu mong muốn.  

Ví dụ, khi content-type là 'application/json", model binder sử dụng lớp JsonInputFormatter để chuyển request body và map vào tham số

Ràng buộc từ Tiêu đề yêu cầu sử dụng [FromHeader]

[FromHeader] ánh xạ các giá trị từ tiêu đề yêu cầu vào tham số của hành động

8

Vô hiệu hóa liên kết với [BindNever]

To for model binder know that not bind cho thuộc tính nào đó

9

Giờ thì mô hình chất kết dính sẽ bỏ qua các thuộc tính Xếp hạng ngay cả khi biểu mẫu có trường Xếp hạng

Bắt buộc ràng buộc với [BindRequired]

Cái này chắc chắn bị đảo ngược với [BindNever]. Trường nào được đánh dấu là BindRequired phải luôn hiển thị trên biểu mẫu và ràng buộc phải thực hiện nếu không thì ModelState. IsValid sẽ sai