Friday, July 29, 2011

Difference between ViewData, ViewBag and TempData in MVC

http://rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp.net-mvc-3-applications

Rachel's BlogHome Subscribe Events User Groups Downloads About
Share with friends!
90 6 8Delicious2StumbleUpon1Email2

"When should I use a ViewBag vs. ViewData vs. TempData objects?" -- a frequent question in online forums, during presentations, and at events. There are enough similarities and differences between these objects that warrant a closer look to see exactly how you can use each of these objects while developing MVC applications.

All three objects are available as properties of both the view and controller. As a rule of thumb, you'll use the ViewData, ViewBag, and TempData objects for the purposes of transporting small amounts of data from and to specific locations (e.g., controller to view or between views). Both the ViewData and ViewBag objects work well in the following scenarios:

Incorporating dropdown lists of lookup data into an entity
Components like a shopping cart
Widgets like a user profile widget
Small amounts of aggregate data
While the TempData object works well in one basic scenario:

Passing data between the current and next HTTP requests
If you need to work with larger amounts of data, reporting data, create dashboards, or work with multiple disparate sources of data, you can use the more heavy duty ViewModel object. See my detailed blog post on ViewModels for more details on working with ViewModels.

ViewData & ViewBag objects
ViewData
ViewData is a dictionary object that you put data into, which then becomes available to the view. ViewData is a derivative of the ViewDataDictionary class, so you can access by the familiar "key/value" syntax.
ViewBag
The ViewBag object is a wrapper around the ViewData object that allows you to create dynamic properties for the ViewBag.
Both the ViewData and ViewBag objects are great for accessing extra data (i.e., outside the data model), between the controller and view. Since views already expect a specific object as their model, this type of data access to extra data, MVC implements it as a property of both views and controllers, making usage and access to these objects easy.

The syntax and usage of the ViewBag, ViewData, and TempData objects are outlined in the following code sample, which populates a featured product object that a view renders as in a bakery's home page:

public class HomeController : Controller{ // ViewBag & ViewData sample public ActionResult Index() { var featuredProduct = new Product { Name = "Special Cupcake Assortment!", Description = "Delectable vanilla and chocolate cupcakes", CreationDate = DateTime.Today, ExpirationDate = DateTime.Today.AddDays(7), ImageName = "cupcakes.jpg", Price = 5.99M, QtyOnHand = 12 }; ViewData["FeaturedProduct"] = featuredProduct; ViewBag.Product = featuredProduct; TempData["FeaturedProduct"] = featuredProduct; return View(); }}
The Index.cshtml view renders the Product object by accessing the code with the same syntax as in the controller. Notice that you'll have to cast the ViewData and TempData objects, but not the ViewBag.

@using FourthCoffee.Models;@{ ViewBag.Title = "Home Page"; var viewDataProduct = ViewData["FeaturedProduct"] as Product; var tempDataProduct = TempData["FeaturedProduct"] as Product; }

Welcome to Fourth Coffee Bakery

Fourth Coffee Bakery
Today's Featured Product is!

@ViewBag.FeaturedProduct.Name

@viewDataProduct.Name

@tempDataProduct.Name

@Html.ActionLink("Test Tempdata","Featured")

The ViewBag object lets you add dynamic properties to it which makes it a very versatile tool.

Although all three display something when this view renders, but the TempData can be troublesome when used in this manner, and here's why...

TempData
TempData is meant to be a very short-lived instance, and you should only use it during the current and the subsequent requests only! Since TempData works this way, you need to know for sure what the next request will be, and redirecting to another view is the only time you can guarantee this. Therefore, 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. Looking back at the previous HomeController code sample means that the TempData object could yield results differently than expected because the next request origin can't be guaranteed. For example, the next request can originate from a completely different machine and browser instance.

As described below, the syntax for using TempData is the same as ViewData.

// TempData samplepublic ActionResult Featured(){ var featuredProduct = new Product { Name = "Assorted Cupcakes", Description = "Delectable vanilla and chocolate cupcakes", CreationDate = DateTime.Today, ExpirationDate = DateTime.Today.AddDays(7), ImageName = "cupcakes.jpg", Price = 5.99M, QtyOnHand = 12 }; ViewData["FeaturedProduct"] = featuredProduct; ViewBag.Product = featuredProduct; TempData["FeaturedProduct"] = featuredProduct; //After the redirect, the ViewBag & ViewData objects are no longer available //Only TempData survives a redirect return new RedirectResult(@"~\Featured\");}
However, once the controller redirects, the ViewBag and ViewData will contain null values. If you inspect the TempData object with debugging tools after the redirect you'll see that it is fully populated with a featured product. This is because the redirect is that only, subsequent, request, so only it can access the TempData object without worry.

@using FourthCoffee.Models;@model FourthCoffee.Models.Product@{ ViewBag.Title = "Details"; var featuredProduct = TempData["FeaturedProduct"] as Product;}
The customary Session object is the backing store for the TempData object, and it is destroyed more quickly than a regular session, i.e., immediately after the subsequent request. Because of its short lived scope, it's great for passing error messages to an error page.

Greg shackles has a very comprehensive blog post that covers just about everything you need to know about TempData.

Now that you've seen how and when to use ViewData, ViewBag, and TempData objects, you might be wondering what to do when using larger sets of data or more complex scenarios. Fortunately, MVC has ways to deal with these commonly needed scenarios.

Thinking outside the ViewBag
Your requirements might need you to represent the following types of data, which do not fit in well when using ViewBag, ViewData, or TempData objects. The MVC 3 framework contains ViewModel objects for when you need more than ViewData. The type of data that suits ViewModels well is as follows:

Master-detail data
Larger sets of data
Complex relational data
Reporting and aggregate data
Dashboards
Data from disparate sources
You'll likely run into these or similar scenarios during the app development process.

Summary
The ViewData and ViewBag objects give you ways to access those extra pieces of data that go alongside your model, however for more complex data, you can move up to the ViewModel. TempData, on the other hand, is geared specifically for working with data on HTTP redirects, so remember to be cautious when using TempData.

16 Comments
Rob Conery said 3 days ago
Hi Rachel - nice post :). I think there's a lot of confusion about this and it's nice to see you tackle it :).

If I may - it might be worth pointing out that *everything* (aside from TempData) gets popped on ViewData, which in turn is popped onto ViewContext - the only question is "how much misdirection do you want".

I think what you're alluding to (correct me if I'm wrong) is handling more complex data structures with a typed class rather than pushing simple key-value bits using ViewData - which is a good approach.

However it's also not exclusive. You can use a ViewModel *with* ViewBag and ViewData:

ViewBag.MyViewModel = new MyViewModel();

Since ViewBag is a wrapper for ViewData (as you mention) - it all cycles down to ViewData as a transport mechanism which is used no matter what you do.

Some people actually prefer this loose association between Controller/View :). For me - I tend to use Dynamic with everything so it doesn't matter :).

Thanks again for writing this post :).


Rachel said 3 days ago
Great points, Rob! Definitely, they can be used together. And yes, that is my approach - ViewBag for more complex, and the others for the simpler things.

Rob Conery said 3 days ago
Not sure I understand... others? It's all ViewData - are you saying "use a Typed View with a ViewModel when your data is complex"?

Sorry to push on this - it can be really confusing to people as there are two separate issues here... and no matter what you're using ViewData :).

Rachel said 3 days ago
Oops!! (sometimes the fingers just type what they want!)

I meant: ViewModel, strongly typed, for more complex scenarios.

The ViewData/ViewBag/TempData for more simple secnarios.

Of course, all in general, as every situation is different and there are always exceptions.

Tiendq said 3 days ago
"The MVC 3 framework contains ViewModel objects for when you need more than ViewData."

I don't think ViewModel is something new in ASP.NET MVC 3. I think you'd better to keep this post for differences between ViewData, ViewBag and TempData, because using ViewModel or not and when is another big topic.

itmeze said 3 days ago
I see Rob Conery point of view...

Beside that, I do admit that having ViewModel, ViewData and ViewBag is a little bit misleading - especially for beginners. This can be somehow unified (as a matter of fact it all ends as a ViewData). Is it kept like that just because of backward compatibility?

TempData is of course a completely different story...

Go for dynamics! :)

Jon said 3 days ago
Just one question, can TempData also be used in scenarios where you need a value to be propagated down to partial views that are rendered through RenderAction in the controller? I had a scenario where the value passed into the URL for a controller action was needed by the partial views too and TempData seemed to be the only way to achieve it.

Amr ElGarhy said 3 days ago
Nice article, I have a question: the tempData get killed after the subsequent request ends, when exactly the ViewData, ViewBag and ViewModel ends?

Harry M said 3 days ago
Theres also a thing called 'PageData' that you can access from Views

Rachel said 2 days ago
Tiendq-

Didn't mean to sound as if I were excluding other verions by using MVC 3 in the sentence as the ViewModel is available in V2 as well.

And yes, agreed, ViewModels are worth their own post, so I have one here just for them :

http://rachelappel.com/use-viewmodels-to-manage-data-amp-organize-code-in-asp.net-mvc-applications



Rachel said 2 days ago
itmeze,

Yes, they can be confusing at times for beginners and some of the features are kept for backwards compatibility.

LOL dynamics!

Rachel said 2 days ago
Amr,

ViewData/Bag live until the end of the current request, which is all you need to get data from the model through the controller and to to view.


Rachel said 2 days ago
Harry,

Yes! it's a handy little object too. Thanks for the pro tip.

Amr ElGarhy said 2 days ago
@Rachel
So this means that TempData has a longer live time, correct?

Also, what are objects in asp.net have the same behavior as ViewData and TempData?

Rachel Appel said 1 day ago
Amr,

Yes, however TempData is restricted to the current and subsequent requests only. So, not much longer. It's really only useful, IMO, with the scenario I described above (redirection).

For ASP.NET Web Forms (I think that's what you're referring to when you say ASP.NET) - you can use the HttpContext.Current.Items collection.


Kristofer Hoch said 20 hours ago
Racheal,

You don't know me, and I only found you because of Rob's blog post about this article.

I have to say this is a great post. It was a bit confusing, but your dialog with Rob cleared it up.

I've subscribed to your news letter.

Sincerely,
Kristofer Hoch

Add a Comment
Name

Email

Url


Comment

Submit Comment

Share with friends!
90 6 8Delicious2StumbleUpon1Email2

Subscribe via email!
Enter your email address:


Powered by Orchard | Hosted by OrcsWeb | © Rachel Appel 2011 Sign In

Monday, January 10, 2011

Differences and Similarities between MVP and MVC Design

http://www.pnpguidance.net/Post/ASPNETMVCFrameworkComparedWebClientSoftwareFactoryWCSF.aspx