TempData, ViewBag and ViewData trong ASP.NET MVC
ASP.NET ViewBag
ViewBag là gì?
ViewBag trong ASP.NET MVC được sử dụng để chuyển dữ liệu tạm thời (không có trong model) từ controller sang view.
ViewBag in MVC là một thuộc tính kiểu dynamic của lớp ControllerBase là lớp cơ sở của lớp Controller.
Thuộc tính Name được gắn vào ViewBag in MVC với ký hiệu dấu chấm và gán giá trị chuỗi “Bill” cho nó trong controller. Thuộc tính này có thể được truy cập trong view như sau @ViewBag.Name.
Bạn có thể gán bất kỳ số thuộc tính và giá trị nào cho ViewBag. Nếu bạn gán cùng một tên thuộc tính nhiều lần cho ViewBag, thì nó sẽ chỉ xem xét giá trị cuối cùng được gán cho thuộc tính.
Tips: Bạn có thể gán một đối tượng kiểu nguyên thủy hoặc kiểu phức tạp làm giá trị cho thuộc tính ViewBag.
Ghi chú: ViewBag trong MVC chỉ truyền dữ liệu từ controller sang view, không chuyển dữ liệu ngược lại. Giá trị ViewBag in MVC sẽ là null nếu xảy ra chuyển hướng (redirect).
Ví dụ sau minh họa cách chuyển dữ liệu từ controller sang view bằng ViewBag.
namespace MVC_BasicTutorials.Controllers { public class StudentController : Controller { IList<Student> studentList = new List<Student>() { new Student() { StudentID=1, StudentName="Steve", Age = 21 }, new Student() { StudentID=2, StudentName="Bill", Age = 25 }, new Student() { StudentID=3, StudentName="Ram", Age = 20 }, new Student() { StudentID=4, StudentName="Ron", Age = 31 }, new Student() { StudentID=5, StudentName="Rob", Age = 19 } }; // GET: Student public ActionResult Index() { ViewBag.TotalStudents = studentList.Count(); return View(); } } }
Trong ví dụ trên, chúng tôi muốn hiển thị tổng số sinh viên trong view. Vì vậy, chúng tôi đã gắn giá trị của studentList.Count() cho thuộc tính TotalStudents của ViewBag.
Bây giờ, trong view Index.cshtml, bạn có thể truy cập thuộc tính ViewBag.TotalStudents, như được hiển thị bên dưới.
<label>Total Students:</label> @ViewBag.TotalStudents
Đầu ra:
Total Students: 5
Trong thực tế, ViewBag trong MVC là một trình bao bọc xung quanh ViewData. Nó sẽ ném ra một ngoại lệ thời gian chạy nếu tên thuộc tính ViewBag khớp với khóa của ViewData.
Hạn chế của ViewBag in C#
- ViewBag không yêu cầu ép kiểu trong khi truy xuất các giá trị từ nó. Điều này có thể ném ra một ngoại lệ thời gian chạy nếu sử dụng sai phương thức trên giá trị.
- ViewBag in C# là kiểu dynamic và bỏ qua kiểm tra kiểu tại thời điểm biên dịch. Vì vậy, tên thuộc tính ViewBag phải khớp trong controller và view khi viết nó theo cách thủ công.
ViewData trong ASP.NET MVC
Trong ASP.NET MVC, ViewData tương tự như ViewBag, truyền dữ liệu từ Controller sang View. ViewData có kiểu Dictionary, trong khi ViewBag là kiểu dynamic. Tuy nhiên, cả hai đều lưu trữ dữ liệu trong cùng một từ điển nội bộ.
ViewData là một từ điển, vì vậy nó chứa các cặp khóa-giá trị trong đó mỗi khóa phải là một chuỗi.
Ghi chú: ViewData chỉ chuyển dữ liệu từ controller sang view nhưng không phải ngược lại. Nó chỉ tồn tại trong yêu cầu hiện tại.
Ví dụ sau minh họa cách chuyển dữ liệu từ controller sang view bằng ViewData.
public ActionResult Index() { IList<Student> studentList = new List<Student>(); studentList.Add(new Student() { StudentName = "Bill" }); studentList.Add(new Student() { StudentName = "Steve" }); studentList.Add(new Student() { StudentName = "Ram" }); ViewData["students"] = studentList; return View(); }
Trong ví dụ trên, studentList được gán cho ViewData[“students”] với “students” là khóa và studentList là giá trị. Bây giờ bạn có thể truy cập ViewData[“students”] trong view, như hình dưới đây.
<ul> @foreach (var std in ViewData["students"] as IList<Student>) { <li> @std.StudentName </li> } </ul>
Ở trên, chúng ta truy xuất giá trị bằng cách sử dụng ViewData[“students”] và ép kiểu nó về một kiểu dữ liệu thích hợp. Bạn cũng có thể thêm các đối tượng KeyValuePair vào ViewData, như được hiển thị bên dưới.
public ActionResult Index() { ViewData.Add("Id", 1); ViewData.Add(new KeyValuePair<string, object>("Name", "Bill")); ViewData.Add(new KeyValuePair<string, object>("Age", 20)); return View(); }
ViewData và ViewBag đều sử dụng cùng một từ điển trong nội bộ. Vì vậy, bạn không thể để ViewData Key trùng với tên thuộc tính của ViewBag, nếu không nó sẽ ném ra một ngoại lệ lúc thực thi.
public ActionResult Index() { ViewBag.Id = 1; ViewData.Add("Id", 1); // throw runtime exception as it already has "Id" key ViewData.Add(new KeyValuePair<string, object>("Name", "Bill")); ViewData.Add(new KeyValuePair<string, object>("Age", 20)); return View(); }
TempData C# trong ASP.NET MVC
TempData trong MVC được sử dụng để chuyển dữ liệu từ view sang controller, controller sang view hoặc từ phương thức hành động này sang phương thức hành động khác của cùng một controller hoặc một controller khác.
TempData lưu trữ dữ liệu tạm thời và tự động xóa dữ liệu đó sau khi truy xuất giá trị.
TempData trong MVC là một thuộc tính trong lớp ControllerBase. Vì vậy, nó có sẵn trong bất kỳ controller hoặc view nào trong ứng dụng ASP.NET MVC.
Ví dụ sau đây cho thấy cách chuyển dữ liệu từ phương thức hành động này sang phương thức hành động khác bằng TempData.
public class HomeController : Controller { public ActionResult Index() { TempData["name"] = "Bill"; return View(); } public ActionResult About() { string name; if(TempData.ContainsKey("name")) { name = TempData["name"].ToString(); // returns "Bill" } return View(); } public ActionResult Contact() { //the following throws exception as TempData["name"] is null //because we already accessed it in the About() action method //name = TempData["name"].ToString(); return View(); } }
Trong ví dụ trên, chúng tôi đã thêm dữ liệu vào TempData trong phương thức hành động Index() và truy cập nó trong phương thức hành động About(). Giả sử rằng người dùng sẽ truy cập trang đầu tiên Index và sau đó đến trang About.
Phần sau chuyển dữ liệu từ phương thức hành động sang view.
public class HomeController : Controller { public ActionResult Index() { TempData["name"] = "Bill"; return View(); } public ActionResult About() { //the following throws exception as TempData["name"] is null //because we already accessed it in the Index.cshtml view //name = TempData["name"].ToString(); return View(); } public ActionResult Contact() { //the following throws exception as TempData["name"] is null //because we already accessed it in the Index.cshtml view //name = TempData["name"].ToString(); return View(); } }
Ở trên, chúng ta đã thêm dữ liệu vào TempData trong phương thức hành động Index(). Vì vậy, chúng ta có thể truy cập nó trong view Index.cshtml, như hình dưới đây. Bởi vì chúng ta đã truy cập nó trong view Index trước, chúng ta không thể truy cập nó ở bất kỳ nơi nào khác.
@{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } @TempData["name"]
Bạn cũng có thể chuyển dữ liệu từ view sang controller, như được hiển thị bên dưới.
@{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } @{ TempData["name"] = "Steve"; }
TempData ở trên có thể được truy cập trong controller, như hình dưới đây.
public class HomeController : Controller { public ActionResult Index() { return View(); } public ActionResult About() { if(TempData.ContainsKey("name")) { name = TempData["name"].ToString(); // returns "Bill" } return View(); } public ActionResult Contact() { //the following throws exception as TempData["name"] is null //because we already accessed it in the About() action method //name = TempData["name"].ToString(); return View(); } }
Mặc dù, TempData tự động xóa khóa-giá trị sau khi được truy cập, bạn vẫn có thể giữ nó cho yêu cầu tiếp theo bằng cách gọi phương thức TempData.Keep().
Ví dụ sau đây cho thấy cách giữ lại giá trị TempData cho các yêu cầu tiếp theo ngay cả khi đã truy cập nó.
public class HomeController : Controller { public ActionResult Index() { TempData["name"] = "Bill"; return View(); } public ActionResult About() { string name; if(TempData.ContainsKey("name")) { name = TempData["name"] as string; } TempData.Keep("name"); // Marks the specified key in the TempData for retention. //TempData.Keep(); // Marks all keys in the TempData for retention return View(); } public ActionResult Contact() { string name; if(TempData.ContainsKey("name")) { data = TempData["name"] as string; } return View(); } }
Viewbag controller to view
Ví dụ trong Controller:
{
ViewBag.Message = “Hello from ViewBag!”;
return View();
}
Ví dụ trong View:
<html>
<head>
<title>My View</title>
</head>
<body>
<h1>@ViewBag.Message</h1>
</body>
</html>
So sánh tổng quan giữa viewbag viewdata and tempdata
Giữa viewbag tempdata và viewdata đều có những sự khác biệt nhau rõ rệt.
Cùng xem so sánh tổng quan về viewbag viewdata and tempdata mà Comdy tổng hợp dưới đây:
- ViewBag và ViewData đều là cách để truyền dữ liệu giữa Controller và View, nhưng ViewBag linh hoạt hơn vì nó là đối tượng động.
- TempData được sử dụng để truyền dữ liệu tạm thời giữa các yêu cầu và giữ dữ liệu cho một thời gian ngắn sau khi yêu cầu kết thúc.
- Tất cả đều không thể giữ trạng thái dữ liệu lâu dài, và không nên được sử dụng để truyền dữ liệu giữa các yêu cầu (ngoại trừ TempData). Trong các trường hợp cần giữ trạng thái dữ liệu lâu dài, thường sử dụng mô hình (Model) hoặc session.
Sự khác nhau giữa viewdata and viewbag
Kiểu dữ liệu
- ViewData: Là một từ khóa (Dictionary) được sử dụng để truyền dữ liệu giữa Controller và View. Dữ liệu được gán và truy xuất thông qua các khóa và giá trị.
- ViewBag: Là một đối tượng động (dynamic) cung cấp thông tin tạm thời giữa Controller và View. Dữ liệu được gán và truy xuất thông qua các thuộc tính của ViewBag.
Biên kiểm soát kiểu tĩnh
- ViewData: Không cung cấp biên kiểm soát kiểu tĩnh, và do đó, kiểm tra kiểu phải được thực hiện khi truy cập dữ liệu.
- ViewBag: Tương tự, cũng không cung cấp biên kiểm soát kiểu tĩnh, và kiểm tra kiểu phải được thực hiện khi truy cập dữ liệu.
Độ linh hoạt
- ViewData: Thường được sử dụng khi cần truyền nhiều dữ liệu hoặc khi muốn kiểm soát chi tiết hơn về tên khóa dữ liệu.
- ViewBag: Linh hoạt hơn do không yêu cầu khai báo tên khóa trước. Bạn có thể sử dụng các thuộc tính của ViewBag mà không cần khai báo chúng trước đó.
Những điểm cần nhớ về ViewBag, ViewData và TempData trong ASP.NET MVC
- ViewBag chèn nội bộ dữ liệu vào từ điển ViewData. Vì vậy, khóa của ViewData và thuộc tính của ViewBag c# KHÔNG được trùng khớp.
- ViewBag chuyển dữ liệu từ Controller sang View, không phải ngược lại.
- ViewBag c# là một thuộc tính kiểu dynamic của lớp ControllerBase là lớp cơ sở của lớp Controller
- ViewData chuyển dữ liệu từ Controller sang View, không phải ngược lại.
- ViewData là một loại từ điển.
- Tuổi thọ của ViewData chỉ kéo dài trong thời gian yêu cầu HTTP hiện tại. Giá trị ViewData sẽ bị xóa nếu xảy ra chuyển hướng.
- Giá trị ViewData phải được ép kiểu thành một kiểu thích hợp trước khi sử dụng nó.
- TempData được sử dụng để chuyển dữ liệu từ view sang controller, controller sang view hoặc từ phương thức hành động này sang phương thức hành động khác của cùng một controller hoặc một controller khác.
- TempData lưu trữ dữ liệu tạm thời và tự động xóa dữ liệu đó sau khi truy xuất giá trị.
- TempData là một loại từ điển.
- TempData tự động xóa khóa-giá trị sau khi được truy cập, bạn có thể giữ nó cho yêu cầu tiếp theo bằng cách gọi phương thức TempData.Keep().
Kết lại
Trên đây là toàn bộ chia sẻ của Comdy về viewbag viewdata tempdata trong ASP.NET core. Hi vọng những kiến thức này là hữu ích và có ý nghĩa với mọi người. Xin cám ơn vì đã theo dõi và ủng hộ.