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

https://stackoverflow.com/a/16950197/3782855

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.

https://stackoverflow.com/a/16950006/3782855

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.

MVC ViewBag Best Practice

ViewBag is a dynamic dictionary.

So when using ViewBag to transfer data between action methods and views, your compiler won't be able to catch if you make a typo in your code when trying to access the ViewBag item in your view. Your view will crash at run time :(

Generally it is a good idea to use a view model to transfer data between your action methods and views.

view model is a simple POCO class which has properties specific to the view.

So if you want to pass some additional data to view, Add a new property to your view model and use that.Strongly typed Views make the code cleaner and more easy to maintain.

With this approach, you don't need to do explicit casting of your viewbag dictionary item to some types back and forth which you have to do with view bag.

public class ProductsForCategoryVm
{
public string CategoryName { set;get; }
public List<ProductVm> Products { set;get;}
}
public class ProductVm
{
public int Id {set;get;}
public string Name { set;get;}
}

And in your action method, create an object of this view model, load the properties and send that to the view.

public ActionResult Category(int id)
{
var vm= new ProductsForCategoryVm();
vm.CategoryName = "Books";
vm.Products= new List<ProductVm> {
new ProductVm { Id=, Name="The Pragmatic Programmer" },
new ProductVm { Id=, Name="Clean Code" }
}
return View(vm);
}

And your view, which is strongly typed to the view model,

@model ProductsForCategoryVm
<h2>@Model.CategoryName</h2>
@foreach(var item in Model.Products)
{
<p>@item.Name</p>
}

Dropdown data ?

A lot of tutorials/books has code samples which uses ViewBag for dropdown data.

I personally still feel that ViewBag's should not be used for this.

It should be a property of type List<SelectListItem> in your view model to pass the dropdown data.

Here is a post with example code on how to do that.

Are there situations where a ViewBag is absolutely necessary?

There are some valid use cases where you can(not necessary) use ViewBag to send data.

For example, you want to display something on your Layout page, you can use ViewBag for that.

Another example is ViewBag.Title (for the page title) present in the default MVC template.

注意ViewBag.AnnouncementForEditors的使用,AnnouncementForEditors是直接加到dynamic类型的ViewBag上的。

public ActionResult Create()
{
ViewBag.AnnouncementForEditors="Be careful";
return View();
}

And in the layout, you can read the ViewBag.AnnouncementForEditors

因为后端代码,加了对应的属性,所以在前端代码里可以直接使用

<body>
<h1>@ViewBag.AnnouncementForEditors</h1>
<div class="container body-content">
@RenderBody()
</div>
</body>

viewbag的更多相关文章

  1. 在Asp.net MVC 3 web应用程序中,我们会用到ViewData与ViewBag,对比一下:

    Asp.net MVC中的ViewData与ViewBag ViewData ViewBag 它是Key/Value字典集合 它是dynamic类型对像 从Asp.net MVC 1 就有了 ASP. ...

  2. MVC中在RAZOR 模板里突然了现了 CANNOT RESOLVE SYMBOL ‘VIEWBAG’ 的错误提示

    然后在Razor中出现了@ViewBag的不可用,@Url不可用,@Html 这些变量都不能用了. 异常提示: 编译器错误消息: CS0426: 类型“XX.Model.System”中不存在类型名称 ...

  3. .NET Mvc中ViewBag、ViewData、TempData如何使用

    ViewBag 获取动态视图数据字典 作用:给视图传递数据,不需要转换类型,由系统动态解析,比ViewData执行性能要差 ViewData   获取或设置视图数据的字典         给视图传递数 ...

  4. Asp.net MVC的ViewData与ViewBag以及TemplateData的使用与区别

    ViewData ViewBag 它是Key/Value字典集合 它是dynamic类型对像 从Asp.net MVC 1 就有了 ASP.NET MVC3 才有 基于Asp.net 3.5 fram ...

  5. ASP.NET MVC中viewData、viewBag和templateData的使用与区别

    一:类型比较 1.1)ViewBag是动态类型(dynamic). 1.2)ViewData是一个字典型的(Dictionary)-->ViewDataDictionary. 1.3)TempD ...

  6. asp.net mvc中ViewData、ViewBag和TempData的详解

    一.ViewData和ViewBag 1.ViewData和ViewBag都是从Action向View传递数据的方式,当然还有其他方式如向View传递Model. 2.ViewData页面查询数据时需 ...

  7. 怎么在js中,访问viewbag,viewdata等等的值

    在js中要访问viewbag,viewdata存储的值, var ss='@ViewBag.name'; 一定要加引号,单双随便,还有, ViewBag一定要写规范,不然会编译错误! 成功者的秘诀就是 ...

  8. ASP.NET MVC中viewData、viewBag和templateData的区别

    在MVC3开始,视图数据可以通过ViewBag属性访问,在MVC2中则是使用ViewData.MVC3中保留了ViewData的使用.ViewBag是动态类型(dynamic),ViewData是一个 ...

  9. ViewBag是如何实现的

    ExpandoObject 在 MVC 3 的时候 Controller 可以通过 ViewBag 将数据传送到 View.如下就是通过 ViewBag 设置页面标题: public ActionRe ...

  10. MVC3之ViewData与ViewBag

    首先先用代码来说话: ViewData: public ActionResult Index() { List<string> colors = new List<string> ...

随机推荐

  1. Vue-resoure 实现get post jsonp请求

    1.之前学习中,如何发起数据请求? 2.常见的数据请求类型?get post jsonp 3.常见的URL请求资源地址 get请求地址:  http://vue.studyit.io/api/getl ...

  2. Flink系列之流式

    本文仅是自己看书.学习过程中的个人总结,刚接触流式,视野面比较窄,不喜勿喷,欢迎评论交流. 1.为什么是流式? 为什么是流式而不是流式系统这样的词语?流式系统在我的印象中是相对批处理系统而言的,用来处 ...

  3. AttributeError: 'NoneType' object has no attribute 'extend'

    Python使用中可能遇到的小问题 AttributeError: 'NoneType' object has no attribute 'extend' 或者AttributeError: 'Non ...

  4. Python使用xlrd、pandas包从Excel读取数据

    #coding=utf-8 # pip install xlrd import xlrd def read_from_xls(filepath,index_col_list): #filepath:读 ...

  5. 基于LPCXpresso54608开发板创建Embedded Wizard UI应用程序

    平台集成和构建开发环境:LPCXpresso 54608入门指南 本文主要介绍了创建一个适用于LPCXpresso54608开发板的Embedded Wizard UI应用程序所需的所有必要步骤.请一 ...

  6. 使用VisualGDB和OpenOCD调试STM32L0开发板

    本教程主要介绍如何配置VisualGDB和OpenOCD来调试STM32L0开发板的固件,使微控制器进入睡眠模式. 我们将创建一个NUCLEO-L031K6开发板的基本工程,并介绍当CPU进入休眠模式 ...

  7. Codeforces Round #524 (Div. 2) Masha and two friends矩形

    题目 题意:    给一个n*m块大的黑白相间的矩形,在这个举行中操作,要先把第一个矩形(左下角坐标(x1,y2),右上角坐标(x2,y2)) 全部涂成白色,再把第二个矩形(左下角坐标(x3,y3), ...

  8. Spring MVC 学习笔记(二)

    6. 视图和视图解析器  ❤  Spring MVC如何解析视图                                  • 请求处理方法执行完成后,最终返回一个ModelAndView对象 ...

  9. 48、[源码]-Spring容器创建-初始化事件派发器、监听器等

    48.[源码]-Spring容器创建-初始化事件派发器.监听器等 8.initApplicationEventMulticaster();初始化事件派发器: 获取BeanFactory 从BeanFa ...

  10. java中日志打印

    目录 一.预先判断日志级别 二.避免无效日志打印 三.区别对待错误日志 四.保证记录完整内容 打印日志,要注意下面4点. 一.预先判断日志级别 对DEBUG.INFO级别的日志,必须使用条件输出或者使 ...