Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does ViewBag in ASP.NET MVC work behind the scenes?

I am reading a book on ASP.NET MVC and I'm wondering how the following example works:

Example #1

Controller

public class MyController : Controller {     public ActionResult Index()     {         ViewBag.MyProperty = 5;          return View();     } } 

View

<h1>@ViewBag.MyProperty</h1> 

Now I understand that ViewBag is a dynamic object, so that's how you can set the property (though I don't know much about dynamic objects, never worked with them.) But how does the view get the specific instance of the ViewBag from the controller, even though we don't pass anything directly?

I thought that the ViewBag could be a public static object, but then any change to it would be global and it wouldn't be specific to a view instance.

Could you elaborate as to how this works behind the scenes?

Example #2

Controller

public class MyController : Controller {     public ActionResult Index()     {         ViewBag.MyProperty = 5;          return View();     }      public ActionResult Index2()     {         ViewBag.MyProperty = 6;          return View();     } } 

Now let's say the Index method is called first, and then the Index2. In the end the value of ViewBag.MyProperty will end up as 6 (the value from Index2). I feel that it is not a good thing to do, but at the same time I feel that I'm thinking in desktop development terms. Maybe it doesn't matter when used with ASP.NET MVC, as the web is stateless. Is this the case?

like image 498
hattenn Avatar asked Jun 05 '13 20:06

hattenn


People also ask

How does ViewBag work in MVC?

The ViewBag in ASP.NET MVC is used to transfer temporary data (which is not included in the model) from the controller to the view. Internally, it is a dynamic type property of the ControllerBase class which is the base class of the Controller class.

What is the purpose of ViewBag property?

The ViewBag feature allows us to define arbitrary properties on a dynamic object and access them in a view. The dynamic object is accessed through the Controller.


2 Answers

ViewBag is a property of ControllerBase, which all controllers must inherit from. It's a dynamic object, that's why you can add new properties to it without getting compile time errors.

It's not static, it's a member of the object. During the request lifetime, the controller instance is created and disposed, so you won't have "concurrency" problems, like overwriting the value.

The View (and its variants) method is not static as well, and this is how the view receives the ViewBag values: during the process of rendering the view, the controller instance has its ViewBag instance as well.

like image 56
Andre Calil Avatar answered Sep 18 '22 15:09

Andre Calil


If you would analyse ControllerBase class you would see that ViewBag property is a "proxy" to ViewData property just to make your source look nicer. (I even remember Scott Hanselman taking interview from Phil Haack where Phil introduced ViewBag property as a shortcut to ViewData and eliminating the need of repeated square brackets and quotes). Even though ViewBag property is exposed as dynamic object it implements a DynamicViewDataDictionary class which works directly with ViewData.

Looking at source code of Controller class you can find this method:

protected internal virtual ViewResult View(string viewName, string masterName, object model) 

So basically when you call return View(); from your controller it creates a new instance of ActionResult class passing ViewData from controller to it's constructor. Instance of ActionResult is then passed to a particular view engine (ASPX, Razor) so it could be used to render a view in question.

Making ViewBag/ViewData public static could be harmful. Each web request to your MVC application creates a new instance of controller. If you'd have ViewData/ViewBag as public static then two concurrent users would share same data from ViewBag/ViewData.

Here is a video. Discussion on ViewBag (formder ViewModel) starts at 04:05

like image 27
Ramunas Avatar answered Sep 18 '22 15:09

Ramunas