18

ViewData and ViewBag allows you to access any data in view that was passed from controller.

The main difference between those two is the way you are accessing the data. In ViewBag you are accessing data using string as keys - ViewBag[“numbers”] In ViewData you are accessing data using properties - ViewData.numbers.

ViewData example

CONTROLLER

 var Numbers = new List<int> { 1, 2, 3 };

          ViewData["numbers"] = Numbers;

VIEW

<ul>
 @foreach (var number in (List<int>)ViewData["numbers"])
 {
     <li>@number</li> 
 }

 </ul>

ViewBag example

CONTROLLER

 var Numbers = new List<int> { 1, 2, 3 };

         ViewBag.numbers = Numbers;

VIEW

<ul>

@foreach (var number in ViewBag.numbers)

{
<li>@number</li> 
}

</ul>

Session is another very useful object that will hold any information.

For instance when user logged in to the system you want to hold his authorization level.

// GetUserAuthorizationLevel - some method that returns int value for user authorization level.

Session["AuthorizationLevel"] = GetUserAuthorizationLevel(userID);

This information will be stored in Session as long as user session is active. This can be changed in Web.config file:

<system.web>
    <sessionState mode="InProc" timeout="30"/>

So then in controller inside the action :

 public ActionResult LevelAccess()
     {
         if (Session["AuthorizationLevel"].Equals(1))
         {
             return View("Level1");
         }

        if (Session["AuthorizationLevel"].Equals(2))
        {
            return View("Level2");
        }

        return View("AccessDenied");
    }

TempData is very similar to ViewData and ViewBag however it will contain data only for one request.

CONTROLLER

// You created a method to add new client.

TempData["ClientAdded"] = "Client has been added";

VIEW

@if (TempData["ClientAdded"] != null)
{ 
   <h3>@TempData["ClientAdded"] </h3>
}

TempData is useful when you want to pass some information from View to Controller. For instance you want to hold time when view was requested.

VIEW

@{
TempData["DateOfViewWasAccessed"] = DateTime.Now;
}

CONTROLLER

if (TempData["DateOfViewWasAccessed"] != null)
   {
    DateTime time = DateTime.Parse(TempData["DateOfViewWasAccessed"].ToString()); 
   }
Adam Bielecki
  • 657
  • 2
  • 6
  • 20
  • Thanks for more info on this! That should be really helpful for most people. – Adam Bielecki Mar 04 '13 at 14:49
  • Is there a question here or is this a blog post? It's fine to answer your own question but it should be done as an answer, not as part of the question. More importantly, this material has already been covered before, such as [What is the right time for ViewData, ViewBag, Session, TempData](http://stackoverflow.com/questions/12676924/what-is-the-right-time-for-viewdata-viewbag-session-tempdata) – Tim M. Mar 04 '13 at 15:26
  • 1
    I will remember that for future and sorry for that. I tried to gave some more examples and maybe some more experienced developers shares their experience as well. – Adam Bielecki Mar 04 '13 at 16:24

4 Answers4

19

ViewBag, ViewData, TempData, Session - how and when to use them?

ViewBag

Avoid it. Use a view model when you can.

The reason is that when you use dynamic properties you will not get compilation errors. It's really easy to change a property name by accident or by purpose and then forget to update all usages.

If you use a ViewModel you won't have that problem. A view model also moves the responsibility of adapting the "M" (i.e. business entities) in MVC from the controller and the view to the ViewModel, thus you get cleaner code with clear responsibilities.

Action

public ActionResult Index()
{
    ViewBag.SomeProperty = "Hello";
    return View();
}

View (razor syntax)

@ViewBag.SomeProperty

ViewData

Avoit it. Use a view model when you can. Same reason as for ViewBag.

Action

public ActionResult Index()
{
    ViewData["SomeProperty"] = "Hello";
    return View();
}

View (razor syntax):

@ViewData["SomeProperty"]

Temp data

Everything that you store in TempData will stay in tempdata until you read it, no matter if there are one or several HTTP requests in between.

Actions

public ActionResult Index()
{
    TempData["SomeName"] = "Hello";
    return RedirectToAction("Details");
}


public ActionResult Details()
{
    var someName = TempData["SomeName"];
}
jgauffin
  • 99,844
  • 45
  • 235
  • 372
  • 1
    "When you need to persist information over several requests" - I am thinking TempData is only good until it is read. I think the use of several request here is a little misleading. – Tommy Mar 04 '13 at 15:02
  • 1
    What I mean is that it stays in the temp data until you read it, no matter if it's two requests or 10 in between. But I get your point and will elaborate. – jgauffin Mar 04 '13 at 15:17
  • 1
    Thanks, I used TempData in my application very often, but I thought it will stay only for one request, not unless you read it. So we can say that it's a bit similar to session, but data can be read only once. – Adam Bielecki Mar 04 '13 at 17:18
  • Would be nice if you add a section that explains 'Sessions' as well. – Shimmy Weitzhandler May 10 '19 at 06:17
3

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.

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.

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();
    }
}
0
namespace TempData.Controllers
{
 public class HomeController : Controller
 {
    public ActionResult Index()
    {
        TempData["hello"] = "test"; // still alive
        return RedirectToAction("About");
    }

    public ActionResult About()
    {
        //ViewBag.Message = "Your application description page.";
        var sonename = TempData["hello"]; // still alive (second time)
        return RedirectToAction("Contact");
    }


    public ActionResult Contact()
    {
        var scondtime = TempData["hello"]; // still alive(third time)
        return View();
    }
    public ActionResult afterpagerender()
    {
        var scondtime = TempData["hello"];//now temp data value becomes null

        return View();
    }
}

}

In above conversation, there is little confuse for everyone. if you look at my above code, tempdata is like viewdata concept but then it is able to redirect other view also. this is first point.

second point: few of them are saying it maintains value till read and few of them are asking that so will it read only time? not so. Actually, you can read any number of time inside your code in one postpack before page render. once page render happened, if you do again postpack (request) means, the tempdata value becomes NULL.

even you are requesting so many time , but the tempdata value is still alive -->this case your number of request should not read temp data value.

Robert
  • 5,278
  • 43
  • 65
  • 115
0

In simple terms:

ViewBag is a dynamic (dynamic: ability to assign more than one value by different programs on the same object) object which is used to send data from controller to view. It can be used when we jump from controller's action to some view. However the value which we get in the view(in the viewbag object) can not be further replicated in other view/controller/js page etc. Meaning: Controller->View (possible). Now this value can not be send to next view/controller. Meaning Controller->View->View/controller/some js file (not possible), to carry this value you need to define some other variable and store viewbag value into it and then send it as a parameter.

Tempdata is very much different than viewbag. It has nothing to do with view at all. It is used when we send data from one action(method) to other action in the same controller. That's the reason we use RedirectToAction whenever sending tempdata value from one action to another. Value of tempdata are not retained when send from controller to veiw (because it is not meant to do so).

ViewData is simillar to viewbag but is a dictionary object. ViewData may require type casting while viewbag may not. It depends on the user which one he may want to use.