在 ASP.NET Core MVC 中从 Controller 向 View 传递数据并非依赖某种“自动绑定”而是通过IActionResult通常是ViewResult作为载体在单次请求生命周期内完成的显式传递。以下是四种核心机制的总结与对比 核心传递机制全景对比机制类型安全智能提示生命周期典型用途推荐度强类型 ViewModel✅ 是✅ 有当前请求页面所有业务数据⭐⭐⭐⭐⭐ViewData❌ 否❌ 无当前请求Layout元数据、少量辅助信息⭐⭐⭐ViewBag❌ 否❌ 无当前请求ViewData 的动态语法糖⭐⭐TempData❌ 否❌ 无当前 下一次请求重定向后的提示消息⭐⭐⭐⭐ 各机制详解1. 强类型 ViewModel首选通过return View(model)传递View 使用model T声明接收。这是 MVC 模式的正统做法。// ControllerreturnView(newProductDetailViewModel{Name手机,Price2999});!-- View --model ProductDetailViewModelh1Model.Name/h1!-- ✅ 编译时检查 智能提示 --优势编译期错误检查、IDE 重构支持、单元测试友好本质Model 被存入ViewData.Model属性model指令只是生成了强类型访问的包装代码2. ViewData弱类型字典ViewDataDictionarystring, object?手动键值对赋值。ViewData[PageTitle]产品详情;h1ViewData[PageTitle]/h1!-- ⚠️ 需手动转换拼写错误运行时才发现 --适用场景Layout 需要的标题/描述、面包屑、激活菜单标识等非业务元数据注意与 ViewBag 共享同一底层字典3. ViewBag动态包装器ViewBag是ViewData的dynamic语法糖本质完全相同。ViewBag.PageTitle产品详情;// 等价于 ViewData[PageTitle]劣势比 ViewData 多一层 dynamic 绑定开销无编译检查重构困难建议新项目优先用 ViewData 替代或直接上 ViewModel4. TempData跨请求传递基于 Session/Cookie 存储读取一次后自动标记删除Peek/Keep 可保留。// Action A: 保存后重定向TempData[SuccessMsg]保存成功;returnRedirectToAction(Index);// Action B (Index): 重定向目标页仍可读取if (TempData[SuccessMsg] is string msg) {divclassalertmsg/div}唯一用途PRG 模式中重定向后的反馈消息禁忌不要用来传业务数据或大量对象 底层统一原理无论用哪种方式数据传递都遵循同一条链路Controller.Action() │ ▼ 数据写入 ViewResult / TempDataProvider │ ▼ MVC 框架执行 ViewResult.ExecuteResultAsync() │ ▼ Razor Engine 渲染 .cshtml │ ▼ Model / ViewData / TempData 从执行上下文中读取关键认知所有传递都是单向、显式、基于请求上下文的。View 不会反向修改 Controller 中的数据表单提交是新的 POST 请求不是回写。 选型决策树需要传数据给 View │ ├── 是页面核心业务数据 → ✅ ViewModel │ ├── 是 Layout/Partial 用的元数据 → ✅ ViewData │ ├── 需要跨越重定向 → ✅ TempData │ └── 以上都不是 → 重新审视设计可能不该传⚠️ 常见反模式警示用 ViewData/ViewBag 传全部业务数据丧失类型安全维护噩梦在 TempData 中存复杂对象序列化开销大Session 膨胀ViewData 和 ViewModel 混传同一份数据冗余且易不一致在 View 中修改 ViewData 并期望影响后续逻辑View 应只读消费数据一句话总结ViewModel 传业务ViewData 传元数据TempData 传消息其余皆不应传。