概述
视图的主要用途是以适当的格式显示数据,即渲染数据。要渲染数据,就必须将数据从控制器传到视图。
对于杂项数据,推荐使用松散的弱类型视图模型传递数据
对于逻辑相关或有一定结构的数据,推荐使用强类型视图模型传递数据
使用弱类型视图模型
查看 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 属性