This article is currently in the process of being translated into Vietnamese (~95% done).
Passing data into Views
Một View có thể tồn tại mà không có Model hay các dữ liệu khác từ backend, nhưng trong hầu hết trường hợp, bạn cần truy cập dữ liệu để Controller có thể đưa vào View. View không cần biết về Controller (tách biệt chức năng), Controller có nhiệm vụ chuẩn bị dữ liệu cho View. Có hai cách chính để thực hiện: thông qua Model, thông qua ViewData/ViewBag. Chúng ta cùng xem các phương thức.
Please notice that there will be a bit of overlap in the information provided by this article and the quick-start article on adding a Model to your project.
Using a (View) Model
Công nghệ là MVC, viết tắt của Model-View-Controller, sử dụng (View) Model là rõ ràng nhất và là cách tiếp cận chung nhất để truyền dữ liệu vào View. Chúng ta sẽ nói thêm về Model trong bài giảng này, nhưng chúng là đối tượng, thường đại diện cho đời sống thực. Bạn cũng sẽ làm quen với khái niệm "View Model" - chúng ta cũng sẽ đi sâu hơn, nhưng mô tả ngắn gọn thì View Model là Model được đưa vào View. Nó có thể là cái gì đó đã tồn tại trong dự án, giống đối tượngUser hoặc Product, hoặc một lớp bạn có thể định nghĩa dữ liệu muốn truy cập từ View.
Một Model không phải là một lớp phức tạp - về lý thuyết nó có thể đơn giản như là String, Integer hay DateTime. Nói cách khác, bất kỳ cái gì trong .NET framework có thể được dùng như Model, nhưng thực tế, Model của bạn thường là lớp chứa vài thuộc tính. Ví dụ, một Model của Product sẽ như sau:
public class Product
{
public string Title { get; set; }
public double Price { get; set; }
}
Liên kết giữa Model và View được thực hiện bởi Controller - nó có thể lấy đầu vào từ người dùng và trả về dữ liệu cho View, ví dụ:
public IActionResult Details(int id)
{
Product product = new Product()
{
Title = "Toilet Paper",
Price = 1.99
};
return View(product);
}
Chú ý làm sao ta có thể đưa product sang View khi gọi phương thức View(). Trong View Product/Details, ta có thể định nghĩa lớp Product như là Model và View có thể dùng @model ở đầu tệp View như sau:
@model HelloMVCWorld.Models.Product
Giờ đây bạn có thể dùng Model của bạn và các thuộc tính như sau:
@model HelloMVCWorld.Models.Product
<h1>@Model.Title</h1>
Price: @Model.Price
Dựa vào thực tế là bạn có thể định nghĩa Model của View, bạn sẽ truy cập vào thành phần của đối tượng thông qua IntelliSense và chương trình của bạn sẽ chạy thông qua quá trình Build, để đảm bảo rằng bạn chỉ có thể dùng thuộc tính/phương thức trong đối tượng Model.
Dynamic Views
Nếu bạn không khai báo Model cho View, sử dung @model trực tiếp. Chúng ta cùng tìm hiểu Dynamic View, tuy không hay sử dụng vì bạn sẽ bỏ qua IntelliSense và kiểm tra thuộc tính trong thời gian biên dịch.
Vậy, bạn nên xem ví dụ trên và bỏ khai báo @model trong View và làm thế nào để chương trình vẫn hoạt động. Trong trường hợp này, Model có thể xem như đối tượngdynamic, bạn có thể truy nhập vào các thuộc tính mà không cần trình biên dịch kiểm tra nó có tồn tại hay không. Tất nhiên điều đó cũng có nghĩa là nếu bạn cố truy cập vào các thuộc tính không tồn tại, thì trang sẽ bị lỗi khi chạy. Khi đó, view động cũng không có nhiều ý nghĩa.
ViewData/ViewBag
Cũng là một cách tiếp cận để đưa dữ liệu vào View, bạn có thể dùng ViewData/ViewBag. Bạn chỉ cần đưa vào Controller và sau đó có thể truy cập vào dữ liệu trong View. Rất dễ dàng như ví dụ sau:
public IActionResult DetailsViewData(int id)
{
ViewBag.ProductTitle = "Toilet Paper";
ViewBag.ProductPrice = 1.99;
return View();
}
Bây giờ bạn có thể truy cập vào dữ liệu trong View dễ dàng nhờ ViewBag:
<h1>@ViewBag.ProducTtitle</h1>
Price: @ViewBag.ProductPrice
Khác biệt chính ở đây là không kiểm tra thuộc tính khi dịch, và không có IntelliSense khi viết. Hay nói cách khác, bạn có thể sai chính tả một thuộc tính nào đó và bạn không biết cho tới khi bạn dùng View. Vậy nên bạn nên dung ViewData/viewBag cho lượng dữ liệu rất nhỏ. Tuy nhiên, bạn nên nhớ rằng bạn có thể tự do kết hợp ViewData/ViewBag với cách dùng View thông thường.
Sự khác biệt giữa ViewData và ViewBag?
Bạn sẽ thấy rằng tôi dùng hai khái niệm cho view động: thuộc tính ViewData và ViewBag. Chúng liên quan tới cùng một thứ, là Dictionary chứa key và value. Tuy nhiên, ViewBag là một đối tượng động, cho phép bạn có thể truy cập dữ liệu nếu chúng là thuộc tính của đối tượng ViewBag, thay vì coi như đầu vào của Dictionary. Bạn có thể dùng các thuộc tính kết hợp nhau, do chúng liên quan tới cùng dữ liệu, để tiện so sánh, ta xem vi dụ sau theo hai cách:
Controller:
public IActionResult DetailsViewData(int id)
{
ViewData["ProductTitle"] = "Toilet Paper";
ViewBag.ProductPrice = 1.99;
return View();
}
View:
<h1>@ViewData["ProducTtitle"]</h1>
Price: @ViewBag.ProductPrice
Chú ý rằng cách dùng ViewData và như vậy theo phương pháp dựa vào Dictionary để đọc và viết ProductTitle, trong khi dùng cách truy cập vào đối tượng để có ProductPrice. Sự khác biệt không quá nhiều, ví dụ khả năng kiểm tra sự có mặt của cặp key/value trong ViewData (dùng phương thức ContainsKey()). Cuối cùng, bạn nên dùng phương pháp mà bạn thấy tiện dụng nhất và nên nhất quán.
Kết luận
Bạn có thể truyền dữ liệu từ Controller sang View bằng nhiều cách, nhưng nên dùng kiểu View. Bạn có thể tận dung IntelliSense và kiểm tra trong lúc biên dịch của các properties và methods mà bạn đang sử dụng.