介绍
在 ASP.NET Core 中, 我们使用 View(视图)渲染数据。视图渲染后返回 HTML 内容。被视图所渲染的数据称为 View Model(视图模型)。在本节中, 我们将学习强类型视图模型和两种弱类型视图模型。
强类型视图模型
如果没有明确说明,当我们提到视图模型时说的都是强类型视图模型。在设计视图时, 可以通过设置视图的 Model 属性为其指定视图模型类型。运行时,Model 属性的值是视图模型类型的实例,它就是实际的视图模型。
下面代码中,我们将视图的视图模型设置为我们上一节创建的 Actor 类,并在 HTML table 中渲染它的数据。
ASP.NET Core 的视图引擎名为 Razor,具体的 Razor 语法我们将在第四单元再讨论。
@model HelloMVC.Models.Actor<html><head> <title>Actor Detail</title></head><body> <h2>Actor Detail</h2> <table border="1"> <tr> <td>ID</td> <td>@Model.ActorID</td> </tr> <tr> <td>Name</td> <td>@($"{Model.FirstName} {Model.LastName}")</td> </tr> </table></body></html>
@model HelloMVC.Models.Actor 表示将视图的 Model 属性的类型设置为 HelloMVC.Models 命名空间中的 Actor 类。视图的整体架构是使用 HTML 创建的,可以直接从前端设计好的静态页面复制过来。
由于视图类只有一个 Model 属性,因此每个视图最多只能有一个强类型视图模型。因此,如果想在单个页面上显示多个对象,就必须创建复合视图模型。
例如,如果你想要显示导演的信息以及 ta 指导的所有电影,你可能就需要设计如下复合视图模型:
public class DirectorFilmsViewModel { public Director Director { get; set; } public IList<Film> Films { get; set; }}
总结一下,在使用强类型视图模型时:
弱类型视图模型
对于某些杂项信息,通常不值得为它们专门创建强类型视图模型类。例如,显式在
标签的页面标题,完全不必像下面这样小题大做为它一个属性就创建一个类:</p>
<pre><code class="lang-csharp">public class HomePageViewModel
{
public string Title {get; set;}
}
</code></pre>
<p>也不推荐将这种额外的属性附加到原本的强视图模型中去:</p>
<pre><code class="lang-csharp">public class DirectorFilmsViewModel
{
public Director Director { get; set; }
public IList<Film> Films { get; set; }
public string Title {get; set;}
}
</code></pre>
<p>这样看起来就很古怪,一个导演电影的视图模型类里面就不该莫名其妙包含一个 Title 属性。并不是说你不能这样做,但 ASP.NET Core 提供了一种更好的处理这类数据的方法 —— 弱类型视图模型。</p>
<p>由于某些历史原因,有两种弱类型视图模型可以用:</p>
<ol>
<li><p><strong>ViewData </strong>属性:一个实现了 IDictionary<string, object> 接口的字典类</p>
</li><li><p><strong>ViewBag </strong>属性:一个 dynamic 对象</p>
</li></ol>
<p>写入数据:</p>
<pre><code class="lang-csharp">ViewData["film"] = new Film{Name = "Transformer", Year = 2017};
ViewBag.title = "Film Details";
ViewBag.film = new Film{Name = "Transformer", Year = 2017}
</code></pre>
<p>渲染数据:</p>
<pre><code class="lang-html"><span>@((ViewData["film"] as File).Name)</span>
<title>@ViewBag.title</title>
<span>@ViewBag.film.Name</span>
</code></pre>
<p>通过 ViewData 传递的数据在渲染时经常需要进行手动转换,通过 ViewBag 传递的数据在渲染时由于没有智能提示,难免出现语法错误,所以要尽量少用弱类型视图模型,更不要用它们传递复杂对象 —— 那是强类型视图模型的工作。</p>