Model Binding trong ASP.NET MVC

Trong phần này, bạn sẽ tìm hiểu về Model Binding (liên kết mô hình) trong ASP.NET MVC.

Để hiểu rõ Model Binding trong MVC, trước tiên hãy xem cách bạn có thể nhận các giá trị yêu cầu HTTP trong phương thức hành động bằng cách sử dụng kiểu ASP.NET truyền thống.

Hình dưới đây cho thấy cách bạn có thể nhận các giá trị từ yêu cầu HTTP GET và HTTP POST bằng cách sử dụng trực tiếp đối tượng Request trong phương thức hành động.

Nhận các giá trị từ đối tượng Request trong ASP.NET MVC

Như bạn có thể thấy trong hình trên, chúng tôi sử dụng đối tượng Request.QueryString và Request (Request.Form) để nhận giá trị từ yêu cầu HTTP GET và HTTP POST.

Truy cập các giá trị yêu cầu bằng cách sử dụng đối tượng Request là một hoạt động cồng kềnh, lãng phí thời gian, nhàm chán, dễ gây ra lỗi và khó bảo trì.

Với Model Binding (liên kết mô hình), ASP.NET MVC tự động chuyển đổi các giá trị trong yêu cầu HTTP (từ chuỗi truy vấn hoặc form biểu mẫu) thành các tham số của phương thức hành động. Các tham số này có thể là kiểu dữ liệu nguyên thủy hoặc kiểu dữ liệu phức tạp.

Binding kiểu dữ liệu nguyên thủy

Yêu cầu HTTP GET nhúng dữ liệu trực tiếp vào chuỗi truy vấn. ASP.NET MVC sẽ tự động chuyển đổi một chuỗi truy vấn thành các tham số của phương thức hành động.

Ví dụ: chuỗi truy vấn "id" trong yêu cầu GET sau đây sẽ tự động được ánh xạ tới tham số id của phương thức hành động Edit().

Binding kiểu dữ liệu nguyên thủy

Bạn cũng có thể có nhiều tham số trong phương thức hành động với các kiểu dữ liệu khác nhau. Các giá trị chuỗi truy vấn sẽ được chuyển đổi thành tham số dựa trên tên phù hợp.

Tips: Model Binding không phân biệt chữ hoa, chữ thường. Vì vậy, tham số "id" có thể là "ID" hoặc "Id".

Ví dụ: http://localhost/student/edit?id = 1&name=John sẽ ánh xạ tới tham số id và name của phương thức hành động Edit() sau.

public ActionResult Edit(int id, string name)
{            
    // do something here
            
    return View();
}

Binding kiểu dữ liệu phức tạp

Model Binding (liên kết mô hình) cũng hoạt động trên các kiểu dữ liệu phức tạp. Model Binding trong ASP.NET MVC tự động chuyển đổi dữ liệu các trường biểu mẫu của yêu cầu HTTP POST thành các thuộc tính của một tham số kiểu dữ liệu phức tạp của một phương thức hành động.

Hãy xem các lớp model sau đây.

public class Student
{
    public int StudentId { get; set; }
    [Display(Name="Name")]
    public string StudentName { get; set; }
    public int Age { get; set; }
    public Standard standard { get; set; }
}

public class Standard
{
    public int StandardId { get; set; }
    public string StandardName { get; set; }
}

Bây giờ, bạn có thể tạo một phương thức hành động có tham số kiểu Student. Trong ví dụ sau, phương thức hành động Edit() (có ActionVerbs là HttpPost) có tham số kiểu Student.

[HttpPost]
public ActionResult Edit(Student std)
{
    var id = std.StudentId;
    var name = std.StudentName;
    var age = std.Age;
    var standardName = std.standard.StandardName;

    //update database here..

    return RedirectToAction("Index");
}

Bây giờ ASP.NET MVC sẽ tự động ánh xạ các trường của biểu mẫu sang các thuộc tính của tham số kiểu Student khi biểu mẫu gửi yêu cầu HTTP POST đến phương thức hành động Edit() như dưới đây.

Binding kiểu dữ liệu phức tạp

Vì vậy, nó tự động liên kết các trường biểu mẫu với tham số loại phức tạp của phương thức hành động.

FormCollection

Ngoài ra, bạn cũng có thể bao gồm tham số kiểu FormCollection trong phương thức hành động để truy xuất tất cả các giá trị từ các trường mẫu xem như dưới đây.

FormCollection

Tuy nhiên FormCollection cũng là một hoạt động cồng kềnh, lãng phí thời gian, nhàm chán, dễ gây ra lỗi và khó bảo trì tương tự như Request.

Thuộc tính Bind

ASP.NET MVC cũng cho phép bạn chỉ định các thuộc tính nào của lớp Model mà bạn muốn liên kết.

Thuộc tính [Bind] sẽ cho phép bạn chỉ định các thuộc tính chính xác mà Model Binding sẽ liên kết.

Trong ví dụ sau, phương thức hành động Edit sẽ chỉ liên kết thuộc tính StudentId và StudentName của Model Student.

[HttpPost]
public ActionResult Edit([Bind(Include = "StudentId, StudentName")] Student std)
{
    var name = std.StudentName;
           
    //write code to update student 
            
    return RedirectToAction("Index");
}

Bạn cũng có thể sử dụng các thuộc tính Exclude để bỏ qua các thuộc tính mà bạn không muốn liên kết như dưới đây.

[HttpPost]
public ActionResult Edit([Bind(Exclude = "Age")] Student std)
{
    var name = std.StudentName;
           
    //write code to update student 
            
    return RedirectToAction("Index");
}

Thuộc tính Bind sẽ cải thiện hiệu suất bằng cách chỉ liên kết các thuộc tính mà bạn cần.

Cơ chế hoạt động của Model Binding

Như bạn đã thấy rằng Model Binding tự động chuyển đổi các giá trị yêu cầu thành một đối tượng kiểu nguyên thủy hoặc kiểu phức tạp.

Model Binding là một quá trình hai bước. Đầu tiên, nó thu thập các giá trị từ yêu cầu HTTP đến và thứ hai, liên kết chúng với các tham số kiểu nguyên thủy hoặc kiểu phức tạp.

Các trình cung cấp giá trị (Value Providers) chịu trách nhiệm thu thập các giá trị từ yêu cầu và Model Binders chịu trách nhiệm liên kết các giá trị với tham số.

Cơ chế hoạt động của Model Binding

Các trình cung cấp giá trị mặc định lấy các giá trị từ các nguồn sau:

  1. Các tham số được liên kết tới hành động trước đó, khi hành động là hành động con.
  2. Các trường của biểu mẫu (Request.Form)
  3. Các giá trị thuộc tính trong phần thân yêu cầu JSON (Request.InputStream), nhưng chỉ khi yêu cầu là một yêu cầu AJAX.
  4. Dữ liệu định tuyến (RouteData.Values)
  5. Các tham số chuỗi truy vấn (Request.QueryString)
  6. Các tập tin đã upload (Request.Files)

ASP.NET MVC có lớp DefaultModelBinder liên kết hiệu quả hầu hết các kiểu mô hình.

Truy cập MSDN để biết thông tin chi tiết về Model Binding.



Bài viết liên quan:

Lớp HtmlHelper trong ASP.NET MVC là gì? Cách sử dụng HtmlHelper để tạo ra các phần tử HTML trong Razor View.

Cách sử dụng cú pháp Razor để viết mã C# hoặc VB.NET trong Razor View trong ASP.NET MVC.

Tìm hiểu cách tạo view cho chức năng chỉnh sửa thông tin sinh viên trong ASP.NET MVC.