ViewBag, ViewData và TempData


209

Bất cứ ai có thể giải thích, khi sử dụng

  1. TempData
  2. Xem túi
  3. Xem dữ liệu

Tôi có một yêu cầu, trong đó tôi cần đặt một giá trị trong bộ điều khiển một, bộ điều khiển đó sẽ chuyển hướng đến Bộ điều khiển Hai và Bộ điều khiển Hai sẽ hiển thị Chế độ xem.

Tôi đã thử sử dụng ViewBag, giá trị bị mất khi tôi đến Bộ điều khiển Hai.

Tôi có thể biết khi nào nên sử dụng và ưu điểm hay nhược điểm?

Cảm ơn


5
Đây là một bài viết tuyệt vời giải thích sự khác biệt.
Beku

1
stackoverflow.com/a/17199709/2015869
Imad Alazani

Câu trả lời:


293

1) TempData

Cho phép bạn lưu trữ dữ liệu sẽ tồn tại để chuyển hướng. Trong nội bộ, nó sử dụng Phiên làm cửa hàng sao lưu, sau khi chuyển hướng được thực hiện, dữ liệu sẽ tự động bị xóa. Mô hình như sau:

public ActionResult Foo()
{
    // store something into the tempdata that will be available during a single redirect
    TempData["foo"] = "bar";

    // you should always redirect if you store something into TempData to
    // a controller action that will consume this data
    return RedirectToAction("bar");
}

public ActionResult Bar()
{
    var foo = TempData["foo"];
    ...
}

2) ViewBag, ViewData

Cho phép bạn lưu trữ dữ liệu trong một hành động của bộ điều khiển sẽ được sử dụng trong chế độ xem tương ứng. Điều này giả định rằng hành động trả về một khung nhìn và không chuyển hướng. Chỉ sống trong yêu cầu hiện tại.

Mô hình như sau:

public ActionResult Foo()
{
    ViewBag.Foo = "bar";
    return View();
}

và theo quan điểm:

@ViewBag.Foo

hoặc với ViewData:

public ActionResult Foo()
{
    ViewData["Foo"] = "bar";
    return View();
}

và theo quan điểm:

@ViewData["Foo"]

ViewBagchỉ là một trình bao bọc động xung quanh ViewDatavà chỉ tồn tại trong ASP.NET MVC 3.

Điều này đang được nói, không ai trong số hai cấu trúc đó nên được sử dụng. Bạn nên sử dụng các mô hình xem và các khung nhìn được gõ mạnh. Vì vậy, mô hình chính xác là như sau:

Xem mô hình:

public class MyViewModel
{
    public string Foo { get; set; }
}

Hoạt động:

public Action Foo()
{
    var model = new MyViewModel { Foo = "bar" };
    return View(model);
}

Quan điểm đánh máy mạnh mẽ:

@model MyViewModel
@Model.Foo

Sau phần giới thiệu ngắn gọn này, hãy trả lời câu hỏi của bạn:

Yêu cầu của tôi là tôi muốn đặt một giá trị trong bộ điều khiển, bộ điều khiển đó sẽ chuyển hướng đến ControllerTwo và Controller2 sẽ hiển thị Chế độ xem.

public class OneController: Controller
{
    public ActionResult Index()
    {
        TempData["foo"] = "bar";
        return RedirectToAction("index", "two");
    }
}

public class TwoController: Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel
        {
            Foo = TempData["foo"] as string
        };
        return View(model);
    }
}

và khung nhìn tương ứng ( ~/Views/Two/Index.cshtml):

@model MyViewModel
@Html.DisplayFor(x => x.Foo)

Cũng có những hạn chế khi sử dụng TempData: nếu người dùng nhấn F5 trên trang đích, dữ liệu sẽ bị mất.

Cá nhân tôi cũng không sử dụng TempData. Đó là bởi vì bên trong nó sử dụng Phiên và tôi vô hiệu hóa phiên trong các ứng dụng của mình. Tôi thích một cách RESTful hơn để đạt được điều này. Đó là: trong hành động điều khiển đầu tiên thực hiện chuyển hướng lưu trữ đối tượng trong kho lưu trữ dữ liệu của bạn và sử dụng id duy nhất được tạo khi chuyển hướng. Sau đó, trên hành động đích sử dụng id này để tìm nạp lại đối tượng được lưu trữ ban đầu:

public class OneController: Controller
{
    public ActionResult Index()
    {
        var id = Repository.SaveData("foo");
        return RedirectToAction("index", "two", new { id = id });
    }
}

public class TwoController: Controller
{
    public ActionResult Index(string id)
    {
        var model = new MyViewModel
        {
            Foo = Repository.GetData(id)
        };
        return View(model);
    }
}

Quan điểm vẫn giữ nguyên.


57
Câu trả lời tuyệt vời, nhưng tôi không đồng ý với tuyên bố giáo điều "không nên sử dụng hai cấu trúc trong số hai cấu trúc đó". Tôi đã tìm thấy một vài cách sử dụng hợp pháp cho ViewBag. Ví dụ: tôi đặt thuộc ViewBag.Titletính trên tất cả các Chế độ xem được sử dụng trong _Layout.cshtmltệp chế độ xem cơ sở của mình . Một trường hợp khác mà tôi sử dụng là đưa thông tin (ví dụ: "Sản phẩm được lưu thành công!") Cho người dùng. Tôi đã đặt một số đánh dấu chung Layout.cshtmlđể hiển thị thông báo nếu được cung cấp và điều này cho phép tôi đặt ViewBag.Messagetrong bất kỳ Hành động nào. Sử dụng thuộc tính ViewModel cho cả hai trường hợp có quá nhiều nhược điểm.
Jesse Webb

22
Tôi phải đồng ý với Jesse, trong khi đây là một mô tả xuất sắc, nói rõ rằng không có lý do chính đáng để sử dụng ViewBag là vấn đề quan điểm, không phải là vấn đề thực tế. Đây chắc chắn là một thực tế tồi khi lạm dụng ViewBag và một số nhà phát triển rơi vào cái bẫy này, nhưng sử dụng một cách trang nhã nó là một tài nguyên mạnh mẽ.
Ron DeFreitas

1
@ ron.defreitas, được rồi, cho tôi biết một lý do chính đáng tại sao bạn sẽ sử dụng ViewBag. Vui lòng mô tả một kịch bản cụ thể, trong thế giới thực, khi ViewBag có một số sử dụng. Vì bạn đang nói rằng, tôi trích dẫn một tài nguyên mạnh mẽ , tôi đoán bạn có một số trường hợp cụ thể trong đó tài nguyên mạnh mẽ này là mạnh mẽ . Vì tôi chưa bao giờ sử dụng nó trong sự nghiệp của mình, tôi sẽ rất vui khi biết cách mọi người sử dụng vũ khí mạnh mẽ này .
Darin Dimitrov

27
Chúng tôi có một tinh hoa ở đây. Darin, Jesse đặc biệt đề cập đến một ví dụ như vậy. Chỉ vì luôn có những cách khác để làm mọi thứ không tự động phủ nhận tính hữu dụng của chúng.
Djentman

2
@DarinDimitrov: Tôi có một kịch bản ngay bây giờ khi tôi cần chuyển một số thông tin cho chế độ xem từ bên trong một phương thức thuộc tính. Sử dụng bộ lọcContext.Controll.ViewData về cơ bản dễ dàng hơn nhiều so với việc cố gắng chuyển nó sang chế độ xem được gõ mạnh. Điều đó nói rằng, cảm ơn bạn đã giải thích, nó rất hữu ích.
Andy

15

ASP.NET MVC cung cấp cho chúng ta ba tùy chọn ViewData, ViewBag và TempData để truyền dữ liệu từ bộ điều khiển sang chế độ xem và trong yêu cầu tiếp theo. ViewData và ViewBag gần như tương tự nhau và TempData thực hiện trách nhiệm bổ sung. Hãy thảo luận hoặc nhận điểm chính về ba đối tượng đó:

Điểm tương đồng giữa ViewBag & ViewData:

  • Giúp duy trì dữ liệu khi bạn chuyển từ bộ điều khiển sang chế độ xem.
  • Được sử dụng để truyền dữ liệu từ bộ điều khiển để xem tương ứng.
  • Cuộc sống ngắn có nghĩa là giá trị trở thành vô giá trị khi chuyển hướng xảy ra. Điều này là do mục tiêu của họ là cung cấp một cách để giao tiếp giữa các bộ điều khiển và các khung nhìn. Đó là một cơ chế giao tiếp trong cuộc gọi máy chủ.

Sự khác biệt giữa ViewBag & ViewData:

  • ViewData là một từ điển của các đối tượng được lấy từ lớp ViewDataDipedia và có thể truy cập bằng cách sử dụng các chuỗi làm khóa.
  • ViewBag là một thuộc tính động tận dụng các tính năng động mới trong C # 4.0.
  • ViewData yêu cầu typecasting cho loại dữ liệu phức tạp và kiểm tra các giá trị null để tránh lỗi.
  • ViewBag không yêu cầu typecasting cho loại dữ liệu phức tạp.

Ví dụ về ViewBag & ViewData:

public ActionResult Index()
{
    ViewBag.Name = "Monjurul Habib";
    return View();
}


public ActionResult Index()
{
    ViewData["Name"] = "Monjurul Habib";
    return View();
} 

Trong chế độ xem:

@ViewBag.Name 
@ViewData["Name"] 

TempData:

TempData cũng là một từ điển có nguồn gốc từ lớp TempDataDipedia và được lưu trữ trong phiên cuộc sống ngắn và nó là một khóa chuỗi và giá trị đối tượng. Sự khác biệt là vòng đời của đối tượng. TempData giữ thông tin cho thời gian của Yêu cầu HTTP. Điều này có nghĩa là chỉ từ trang này sang trang khác. Điều này cũng hoạt động với chuyển hướng 302/303 vì nó nằm trong cùng một Yêu cầu HTTP. Giúp duy trì dữ liệu khi bạn chuyển từ bộ điều khiển này sang bộ điều khiển khác hoặc từ hành động này sang hành động khác. Nói cách khác, khi bạn chuyển hướng, thì Temp Tempataata giúp duy trì dữ liệu giữa các chuyển hướng đó. Nó sử dụng nội bộ các biến phiên. Sử dụng dữ liệu tạm thời trong yêu cầu hiện tại và sau đó chỉ có nghĩa là nó được sử dụng khi bạn chắc chắn rằng yêu cầu tiếp theo sẽ được chuyển hướng đến chế độ xem tiếp theo. Nó yêu cầu typecasting cho loại dữ liệu phức tạp và kiểm tra các giá trị null để tránh lỗi.

public ActionResult Index()
{
  var model = new Review()
            {
                Body = "Start",
                Rating=5
            };
    TempData["ModelName"] = model;
    return RedirectToAction("About");
}

public ActionResult About()
{
    var model= TempData["ModelName"];
    return View(model);
}

Cơ chế cuối cùng là Phiên làm việc giống như ViewData, giống như một Từ điển lấy một chuỗi cho khóa và đối tượng cho giá trị. Cái này được lưu vào Cookie khách và có thể được sử dụng trong một thời gian dài hơn nhiều. Nó cũng cần xác minh thêm để không bao giờ có bất kỳ thông tin bí mật. Về ViewData hoặc ViewBag, bạn nên sử dụng nó một cách thông minh để thực hiện ứng dụng. Bởi vì mỗi hành động trải qua toàn bộ vòng đời của yêu cầu mvc asp.net thông thường. Bạn có thể sử dụng ViewData / ViewBag trong hành động của con bạn nhưng hãy cẩn thận rằng bạn không sử dụng nó để điền dữ liệu không liên quan có thể gây ô nhiễm bộ điều khiển của bạn.


11

TempData

Về cơ bản, nó giống như một DataReader, một khi đã đọc, dữ liệu sẽ bị mất.

Kiểm tra video này

Thí dụ

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC!";
        TempData["T"] = "T";
        return RedirectToAction("About");
    }

    public ActionResult About()
    {
        return RedirectToAction("Test1");
    }

    public ActionResult Test1()
    {
        String str = TempData["T"]; //Output - T
        return View();
    }
}

Nếu bạn chú ý đến đoạn mã trên, RedirectToAction không có tác động đến TempData cho đến khi TempData được đọc. Vì vậy, một khi TempData được đọc, các giá trị sẽ bị mất.

Làm thế nào tôi có thể giữ TempData sau khi đọc?

Kiểm tra đầu ra trong Phương thức hành động Thử nghiệm 1 và Thử nghiệm 2

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC!";
        TempData["T"] = "T";
        return RedirectToAction("About");
    }

    public ActionResult About()
    {
        return RedirectToAction("Test1");
    }

    public ActionResult Test1()
    {
        string Str = Convert.ToString(TempData["T"]);
        TempData.Keep(); // Keep TempData
        return RedirectToAction("Test2");
    }

    public ActionResult Test2()
    {
        string Str = Convert.ToString(TempData["T"]); //OutPut - T
        return View();
    }
}

Nếu bạn chú ý đến đoạn mã trên, dữ liệu sẽ không bị mất sau RedirectToAction cũng như sau khi đọc Dữ liệu và lý do là, Chúng tôi đang sử dụng TempData.Keep() . có phải vậy không

Bằng cách này, bạn có thể làm cho nó tồn tại miễn là bạn muốn trong các bộ điều khiển khác.

ViewBag / ViewData

Dữ liệu sẽ tồn tại ở Chế độ xem tương ứng


4

TempData trong Asp.Net MVC là một trong những tính năng rất hữu ích. Nó được sử dụng để truyền dữ liệu từ yêu cầu hiện tại sang yêu cầu tiếp theo. Nói cách khác, nếu chúng ta muốn gửi dữ liệu từ trang này sang trang khác trong khi chuyển hướng xảy ra, chúng ta có thể sử dụng TempData, nhưng chúng ta cần xem xét mã trong để đạt được tính năng này trong MVC. Bởi vì tuổi thọ của TempData rất ngắn và chỉ nằm cho đến khi chế độ xem mục tiêu được tải đầy đủ. Nhưng, chúng ta có thể sử dụng phương thức Keep () để duy trì dữ liệu trong TempData.

Đọc thêm


3

ViewBag, ViewData, TempData và View State trong MVC

http://royalarun.blogspot.in/2013/08/viewbag-viewdata-tempdata-and-view.html

ASP.NET MVC cung cấp cho chúng ta ba tùy chọn ViewData, VieBag và TempData để truyền dữ liệu từ bộ điều khiển sang chế độ xem và trong yêu cầu tiếp theo. ViewData và ViewBag gần như tương tự nhau và TempData thực hiện trách nhiệm bổ sung.

Điểm tương đồng giữa ViewBag & ViewData:

Giúp duy trì dữ liệu khi bạn chuyển từ bộ điều khiển sang chế độ xem. Được sử dụng để truyền dữ liệu từ bộ điều khiển để xem tương ứng. Cuộc sống ngắn có nghĩa là giá trị trở thành vô giá trị khi chuyển hướng xảy ra. Điều này là do mục tiêu của họ là cung cấp một cách để giao tiếp giữa các bộ điều khiển và các khung nhìn. Đó là một cơ chế giao tiếp trong cuộc gọi máy chủ.

Sự khác biệt giữa ViewBag & ViewData:

ViewData là một từ điển của các đối tượng được lấy từ lớp ViewDataDipedia và có thể truy cập bằng cách sử dụng các chuỗi làm khóa. ViewBag là một thuộc tính động tận dụng các tính năng động mới trong C # 4.0. ViewData yêu cầu typecasting cho loại dữ liệu phức tạp và kiểm tra các giá trị null để tránh lỗi. ViewBag không yêu cầu typecasting cho loại dữ liệu phức tạp.

Ví dụ về ViewBag & ViewData:

public ActionResult Index()

{  
    ViewBag.Name = "Arun Prakash";
    return View();    
}

public ActionResult Index()  
{
    ViewData["Name"] = "Arun Prakash";
    return View(); 
}

Trong phần Xem, chúng tôi gọi như dưới đây:

@ViewBag.Name   
@ViewData["Name"]

TempData:

Giúp duy trì dữ liệu khi bạn chuyển từ bộ điều khiển này sang bộ điều khiển khác hoặc từ hành động này sang hành động khác. Nói cách khác, khi bạn chuyển hướng, thì Temp Tempataata giúp duy trì dữ liệu giữa các chuyển hướng đó. Nó sử dụng nội bộ các biến phiên. TempData có nghĩa là một ví dụ rất ngắn và bạn chỉ nên sử dụng nó trong các yêu cầu hiện tại và các yêu cầu tiếp theo

Kịch bản duy nhất mà việc sử dụng TempData sẽ hoạt động đáng tin cậy là khi bạn chuyển hướng. Điều này là do chuyển hướng giết chết yêu cầu hiện tại (và gửi mã trạng thái HTTP 302 Đối tượng được di chuyển đến máy khách), sau đó tạo một yêu cầu mới trên máy chủ để phục vụ chế độ xem được chuyển hướng.

Nó yêu cầu typecasting cho loại dữ liệu phức tạp và kiểm tra các giá trị null để tránh lỗi.

public ActionResult Index()
{   
   var model = new Review()  
   {  
      Body = "Start",  
      Rating=5  
   };  

    TempData["ModelName"] = model;    
    return RedirectToAction("About");   
} 

public ActionResult About()       
{  
    var model= TempData["ModelName"];  
    return View(model);   
}  

1
void Keep()

Calling this method with in the current action ensures that all the items in TempData are not removed at the end of the current request.

    @model MyProject.Models.EmpModel;
    @{
    Layout = "~/Views/Shared/_Layout.cshtml";
    ViewBag.Title = "About";
    var tempDataEmployeet = TempData["emp"] as Employee; //need typcasting
    TempData.Keep(); // retains all strings values
    } 

void Keep(string key)

Calling this method with in the current action ensures that specific item in TempData is not removed at the end of the current request.

    @model MyProject.Models.EmpModel;
    @{
    Layout = "~/Views/Shared/_Layout.cshtml";
    ViewBag.Title = "About";
    var tempDataEmployeet = TempData["emp"] as Employee; //need typcasting
    TempData.Keep("emp"); // retains only "emp" string values
    } 

1

TempData sẽ luôn có sẵn cho đến khi đọc lần đầu tiên, một khi bạn đọc nó, nó không còn hữu dụng nữa để truyền thông điệp nhanh chóng để xem nó sẽ biến mất sau lần đọc đầu tiên. ViewBag Hữu ích hơn khi truyền nhanh dữ liệu vào chế độ xem, thông thường bạn nên chuyển tất cả dữ liệu sang chế độ xem qua mô hình, nhưng có trường hợp khi bạn mô hình đến trực tiếp từ lớp được ánh xạ vào cơ sở dữ liệu như khung thực thể trong trường hợp đó bạn không Không có gì để thay đổi mô hình của bạn để truyền một phần dữ liệu mới, bạn có thể dán nó vào viewbag ViewData chỉ là phiên bản được lập chỉ mục của ViewBag và được sử dụng trước MVC3


0

Ngoài ra phạm vi là khác nhau giữa viewbag và temptdata. viewbag dựa trên chế độ xem đầu tiên (không được chia sẻ giữa các phương thức hành động) nhưng temptdata có thể được chia sẻ giữa một phương thức hành động và chỉ một phương thức khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.