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

旧巷老猫 提交于 2019-12-03 10:24:32
Andre Calil

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.

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

ViewBag is a property of ControllerBase. It is defined as follows:

public Object ViewBag { get; }

Note that this signature is actually incorrect. Here's what the source code actually looks like:

public dynamic ViewBag {
        get {
            if (_dynamicViewDataDictionary == null) {
                _dynamicViewDataDictionary = new DynamicViewDataDictionary(() => ViewData);
            }
            return _dynamicViewDataDictionary;
        }
    }

_dynamicViewDataDictionary is an ExpandoObject; you can add properties to it at runtime. Its lifetime is the same as that of the controller, which is the lifetime of the HTTP request.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!