概述

视图的主要用途是以适当的格式显示数据,即渲染数据。要渲染数据,就必须将数据从控制器传到视图。

  • 对于杂项数据,推荐使用松散的弱类型视图模型传递数据

  • 对于逻辑相关或有一定结构的数据,推荐使用强类型视图模型传递数据

使用弱类型视图模型

查看 ASP.NET Core 源码,可以看到 Microsoft.AspNetCore.Mvc.Controller 类包含 ViewBag 和 ViewData 属性:

  1. namespace Microsoft.AspNetCore.Mvc
  2. {
  3. public abstract class Controller : /*base classes/interfaces*/
  4. {
  5. [Dynamic]
  6. public dynamic ViewBag { get; }
  7. [ViewDataDictionary]
  8. public ViewDataDictionary ViewData { get; set; }
  9. // ... other members
  10. }
  11. }

如前所述,视图文件(.cshtml)中的代码将被转换为视图页面类。视图页面类之间的继承关系是:
IRazorPage -> RazorPageBase -> RazorPage -> RazorPage -> 你的视图页面类。

RazorPageBase 类里面定义了 ViewBag 属性,RazorPage 类里面定义了 ViewData 属性。这意味着你的视图页面类里面也一定会有这两个属性。

当 Action 调用 View 方法渲染视图时,Razor 引擎将创建一个视图页面类的实例,然后将该 Controller(控制器)的 ViewBag 和 ViewData 属性值赋给视图实例的 ViewBag 和 ViewData 属性。

使用强类型视图模型

之前已经讲过如何设计强类型视图模型,此处聚焦于如何使用视图渲染它。

使用 @model 指令为视图指定强类型视图模型。例如之前示例中的 @model MyWebApp.Models.ProductListVM 就是将视图类的 Model 属性设置为 ProductListVM。运行时,Model 的值可以是 ProductListVM 的实例,也可以是 null。

@model 的类型就是 TModel,Model 属性的类型也是 TModel。如果没有 @model 指令,TModel 将被设置为 System.Object 类。

RazorPage 源码:

  1. namespace Microsoft.AspNetCore.Mvc.Razor
  2. {
  3. public abstract class RazorPage<TModel> : RazorPage
  4. {
  5. public TModel Model { get; set; }
  6. // other members ...
  7. }
  8. }

设置 Model 值的方法:

  1. public class YourController : Controller
  2. {
  3. public IActionResult YourAction()
  4. {
  5. var vm = /* create the instance of the view model */;
  6. // business logics ...
  7. return View("YourView", vm);
  8. }
  9. }

查阅源码,可以找到 YourAction 调用的 View 方法:

  1. [NonAction]
  2. public virtual ViewResult View(string viewName, object model);

同样,你也可以在视图代码里面使用 Model 属性:

  1. @foreach (var p in this.Model.Products)
  2. {
  3. <tr>
  4. <td>@p.ID</td><td>@p.Name</td><td>@p.Price</td><td>@(p.Price * rate)</td>
  5. </tr>
  6. }

@model vs @Model

很多刚接触 ASP.NET Core 的程序员都会分不清 @model 和 @Model。一旦你熟悉了 Razor 语法,就会明白:

  • @model 是引导设置视图模型类型的指令

  • @Model(或 @this.Model)用于访问视图实例的 Model 属性