ViewData 和 ViewBag 是 ASP.NET Core MVC 中控制器向视图临时传值的轻量方式,本质相同、仅限单次请求,适合传少量非结构化数据,但缺乏类型安全和编译检查,推荐优先使用强类型 ViewModel。

ASP.NET Core MVC 中向视图传递数据,最常用、最轻量的方式就是 ViewData 和 ViewBag。它们本质相同,都是控制器向视图“临时传值”的快捷通道,适用于单次请求内的简单数据共享。
ViewData 是字典,需要类型转换
ViewData 是一个继承自 IDictionary 的动态字典,键是字符串,值是 object 类型。在控制器中赋值后,视图里必须显式转换类型才能安全使用。
- 控制器中写法:ViewData["Title"] = "用户列表"; ViewData["Count"] = 12;
- 视图中用法:@ViewData["Title"](显示为 string);@((int)ViewData["Count"])(必须强转,否则编译不报错但运行可能出错)
- 注意:如果 key 不存在或类型不匹配,运行时会抛
NullReferenceException或InvalidCastException
ViewBag 是动态包装器,写起来更省事
ViewBag 是对 ViewData 的动态封装(底层仍是 ViewData),利用 C# 的 dynamic 特性,允许用点语法访问属性,无需引号和类型转换。
- 控制器中写法:ViewBag.Title = "用户列表"; ViewBag.Count = 12;
- 视图中用法:@ViewBag.Title、@ViewBag.Count(自动解包,看起来像普通属性)
- 缺点:没有编译时检查——拼错属性名(如
@ViewBag.Titile)不会报错,运行时才为 null;也不支持 IntelliSense 提示
它们的共同特点和适用场景
ViewData 和 ViewBag 都只在当前请求生命周期内有效,下一次请求就清空。适合传少量、非结构化、一次性的数据,比如页面标题、提示消息、开关标志等。
- 不能传复杂模型对象(建议用
ViewData.Model或直接 return View(model)) - 不适合跨 Action 传值(要用 TempData)
- 不推荐在大型项目中大量使用——可维护性差,容易出错,测试困难
- 常见用法举例:ViewBag.IsAdmin = User.IsInRole("Admin");,然后视图里
@if (ViewBag.IsAdmin) { ... }
一个小提醒:别混用,优先考虑强类型模型
ViewData 和 ViewBag 底层共用同一份数据容器,所以 ViewBag.Name = "张三" 等价于 ViewData["Name"] = "张三"。混着用容易混乱,选一种风格保持统一即可。
真正要传业务数据,比如用户列表、表单数据,应优先使用强类型视图模型(ViewModel):定义类 → 控制器 new 并传入 → 视图顶部声明 @model UserListViewModel。这样有类型安全、智能提示、易于单元测试,才是 MVC 的推荐做法。
基本上就这些。ViewData/ViewBag 是快刀,用对地方很顺手;但别当主菜,该上 ViewModel 还得上。










