概述
视图的主要用途是以适当的格式显示数据,即渲染数据。要渲染数据,就必须将数据从控制器传到视图。
对于杂项数据,推荐使用松散的弱类型视图模型传递数据
对于逻辑相关或有一定结构的数据,推荐使用强类型视图模型传递数据
使用弱类型视图模型
查看 ASP.NET Core 源码,可以看到 Microsoft.AspNetCore.Mvc.Controller 类包含 ViewBag 和 ViewData 属性:
namespace Microsoft.AspNetCore.Mvc{public abstract class Controller : /*base classes/interfaces*/{[Dynamic]public dynamic ViewBag { get; }[ViewDataDictionary]public ViewDataDictionary ViewData { get; set; }// ... other members}}
如前所述,视图文件(.cshtml)中的代码将被转换为视图页面类。视图页面类之间的继承关系是:
IRazorPage -> RazorPageBase -> RazorPage -> RazorPage
RazorPageBase 类里面定义了 ViewBag 属性,RazorPage
当 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
namespace Microsoft.AspNetCore.Mvc.Razor{public abstract class RazorPage<TModel> : RazorPage{public TModel Model { get; set; }// other members ...}}
设置 Model 值的方法:
public class YourController : Controller{public IActionResult YourAction(){var vm = /* create the instance of the view model */;// business logics ...return View("YourView", vm);}}
查阅源码,可以找到 YourAction 调用的 View 方法:
[NonAction]public virtual ViewResult View(string viewName, object model);
同样,你也可以在视图代码里面使用 Model 属性:
@foreach (var p in this.Model.Products){<tr><td>@p.ID</td><td>@p.Name</td><td>@p.Price</td><td>@(p.Price * rate)</td></tr>}
@model vs @Model
很多刚接触 ASP.NET Core 的程序员都会分不清 @model 和 @Model。一旦你熟悉了 Razor 语法,就会明白:
@model 是引导设置视图模型类型的指令
@Model(或 @this.Model)用于访问视图实例的 Model 属性
