MVC 的ViewBag, ViewData and TempData使用與區別

Could any body explain, when to use

  1. TempData
  2. ViewBag
  3. ViewData

I have a requirement, where I need to set a value in a controller one, that controller will redirect to Controller Two and Controller Two will render the View.

I have tried to use ViewBag, the value gets lost by the time I reach Controller Two.

Can I know when to use and advantages or disadvantages?

Thanks

share|edit|flag
 
2
 
This is a great post that explains the differences. –  Beku Nov 3 '11 at 10:23
1
 
great question. –  Sachin Kainth Mar 20 at 14:05
 
stackoverflow.com/a/17199709/2015869 –  PKKG Jun 19 at 23:14
 
add comment

4 Answers

up vote105down voteaccepted

1)TempData

Allows you to store data that will survive for a redirect. Internally it uses the Session as baking store, it's just that after the redirect is made the data is automatically evicted. The pattern is the following:

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

Allows you to store data in a controller action that will be used in the corresponding view. This assumes that the action returns a view and doesn't redirect. Lives only during the current request.

The pattern is the following:

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

and in the view:

@ViewBag.Foo

or with ViewData:

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

and in the view:

@ViewData["Foo"]

ViewBag is just a dynamic wrapper around ViewData and exists only in ASP.NET MVC 3.

This being said, none of those two constructs should ever be used. You should use view models and strongly typed views. So the correct pattern is the following:

View model:

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

Action:

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

Strongly typed view:

@model MyViewModel
@Model.Foo

After this brief introduction let's answer your question:

My requirement is I want to set a value in a controller one, that controller will redirect to ControllerTwo and Controller2 will render the View.

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);
    }
}

and the corresponding view (~/Views/Two/Index.cshtml):

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

There are drawbacks of using TempData as well: if the user hits F5 on the target page the data will be lost.

Personally I don't use TempData neither. It's because internally it uses Session and I disable session in my applications. I prefer a more RESTful way to achieve this. Which is: in the first controller action that performs the redirect store the object in your data store and user the generated unique id when redirecting. Then on the target action use this id to fetch back the initially stored object:

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);
    }
}

The view stays the same.

share|edit|flag
 
4
 
@Darin , I really appreciate your great work. –  Frank Myat Thu Feb 23 '12 at 2:56
14
 
Great answer, but I disagree with the dogmatic statement "none of those two constructs should ever be used". I have found a couple legitimate usages for the ViewBag. For example, I set a ViewBag.Titleproperty on all my Views which gets used in my _Layout.cshtml base view file. Another case where I use it is giving info-messages (e.g. "Product saved successfully!") to the users. I placed some generic markup in Layout.cshtml to render a message if provided and this allows me to setViewBag.Message in any Action. Using a ViewModel property for either case has too many disadvantages. –  Jesse Webb Nov 14 '12 at 19:53
8
 
I'd have to agree with Jesse, while this is an excellent description, blatantly stating there is no good reason to use ViewBag is a matter of a matter of opinion, no a matter of fact. It is certainly a bad practice to overuse the ViewBag, and some developers fall into this trap, but tastefully used it is a powerful resource. –  ron.defreitas Dec 6 '12 at 16:19
1
 
@ron.defreitas, alright, tell me then one good reason why would you use ViewBag. Please describe a specific, real world scenario, when ViewBag has some use. Since you are saying that it is, I quote a powerful resource, I guess you have some specific cases where this powerful resource is powerful. Since I've never used it in my career, I would be very happy to learn how people are using this powerful weapon.–  Darin Dimitrov Dec 6 '12 at 21:22 
9
 
We have an elitist over here. Darin, Jesse specifically mentioned one such example. Just because there are always other ways of doing things does not automatically negate their usefulness. –  Djentleman Dec 12 '12 at 1:17
 
add / show 3 more comments

ASP.NET MVC offers us three options ViewData, ViewBag, and TempData for passing data from controller to view and in next request. ViewData and ViewBag are almost similar and TempData performs additional responsibility. Lets discuss or get key points on those three objects:

Similarities between ViewBag & ViewData :

  • Helps to maintain data when you move from controller to view.
  • Used to pass data from controller to corresponding view.
  • Short life means value becomes null when redirection occurs. This is because their goal is to provide a way to communicate between controllers and views. It’s a communication mechanism within the server call.

Difference between ViewBag & ViewData:

  • ViewData is a dictionary of objects that is derived from ViewDataDictionary class and accessible using strings as keys.
  • ViewBag is a dynamic property that takes advantage of the new dynamic features in C# 4.0.
  • ViewData requires typecasting for complex data type and check for null values to avoid error.
  • ViewBag doesn’t require typecasting for complex data type.

ViewBag & ViewData Example:

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


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

In View:

@ViewBag.Name 
@ViewData["Name"] 

TempData:

TempData is also a dictionary derived from TempDataDictionary class and stored in short lives session and it is a string key and object value. The difference is that the life cycle of the object. TempData keep the information for the time of an HTTP Request. This mean only from one page to another. This also work with a 302/303 redirection because it’s in the same HTTP Request. Helps to maintain data when you move from one controller to other controller or from one action to other action. In other words when you redirect, “TempData” helps to maintain data between those redirects. It internally uses session variables. Temp data use during the current and subsequent request only means it is use when you are sure that next request will be redirecting to next view. It requires typecasting for complex data type and check for null values to avoid error. Generally used to store only one time messages like error messages, validation messages.

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

The last mechanism is the Session which work like the ViewData, like a Dictionary that take a string for key and object for value. This one is stored into the client Cookie and can be used for a much more long time. It also need more verification to never have any confidential information. Regarding ViewData or ViewBag you should use it intelligently for application performance. Because each action goes through the whole life cycle of regular asp.net mvc request. You can use ViewData/ViewBag in your child action but be careful that you are not using it to populate the unrelated data which can pollute your controller.

share|edit|flag
  add comment

TempData

Basically it's like a DataReader, once read, data will be lost.

Check this Video

Example

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();
    }
}

If you pay attention to the above code, RedirectToAction has no impact over the TempData until TempData is read. So, once TempData is read, values will be lost.

How can i keep the TempData after reading?

Check the output in Action Method Test 1 and Test 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();
    }
}

If you pay attention to the above code, data is not lost after RedirectToAction as well as after Reading the Data and the reason is, We are using TempData.Keep(). is that

In this way you can make it persist as long as you wish in other controllers also.

ViewBag/ViewData

The Data will persist to the corresponding View

share|edit|flag
  add comment

ViewBag, ViewData, TempData and View State in MVC

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

ASP.NET MVC offers us three options ViewData, VieBag and TempData for passing data from controller to view and in next request. ViewData and ViewBag are almost similar and TempData performs additional responsibility.

Similarities between ViewBag & ViewData :

Helps to maintain data when you move from controller to view. Used to pass data from controller to corresponding view. Short life means value becomes null when redirection occurs. This is because their goal is to provide a way to communicate between controllers and views. It’s a communication mechanism within the server call.

Difference between ViewBag & ViewData:

ViewData is a dictionary of objects that is derived from ViewDataDictionary class and accessible using strings as keys. ViewBag is a dynamic property that takes advantage of the new dynamic features in C# 4.0. ViewData requires typecasting for complex data type and check for null values to avoid error. ViewBag doesn’t require typecasting for complex data type.

ViewBag & ViewData Example:

public ActionResult Index()

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

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

In View, we call like below:

@ViewBag.Name   
@ViewData["Name"]

TempData:

Helps to maintain data when you move from one controller to other controller or from one action to other action. In other words when you redirect, “Tempdata” helps to maintain data between those redirects. It internally uses session variables. TempData is meant to be a very short-lived instance, and you should only use it during the current and the subsequent requests only

The only scenario where using TempData will reliably work is when you are redirecting. This is because a redirect kills the current request (and sends HTTP status code 302 Object Moved to the client), then creates a new request on the server to serve the redirected view.

It requires typecasting for complex data type and check for null values to avoid error.

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);   
}  
share|edit|flag
  add comment
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章