原文:Views Overview

作者:Steve Smith

翻译:姚阿勇(Dr.Yao)

校对:高嵩(Jack)

ASP.NET MVC Core 的控制器可以利用 视图 返回格式化结果。

什么是视图?

在模型-视图-控制器(MVC)模式中,视图 封装用户与应用交互的表现细节。视图是带有嵌入代码的 HTML 模版,用以生成发送给客户端的内容。视图采用 Razor 语法,该语法允许以最小的代码量或复杂度与 HTML 进行编码交互。

ASP.NET Core MVC 视图默认以 .cshtml 文件保存在应用程序的 Views 文件夹里面。通常,每个控制器都会有自己的文件夹,里面是对应控制器操作的视图。

除了对应操作的视图,局部视图布局,以及其他特定视图文件可以用来帮助减少重复并允许在应用视图里重用。

使用视图的好处

视图在 MVC 应用中提供关注点分离,将用户界面层级的标记从业务逻辑中封装出来。ASP.NET MVC 视图采用Razor 语法在 HTML 标记和服务端逻辑之间进行轻松切换。通常,可以通过布局与共享指令或者局部视图对应用的用户界面中重复的外观轻松地进行复用。

创建视图

属于某个控制器的视图创建在 Views/[ControllerName] 文件夹下。在控制器之间共用的视图则放在 /Views/Shared 文件夹下。将视图文件命名为与其关联的控制器操作一样的名字,并添加 .cshtml 文件扩展名。例如,为 Home 控制器的 About 操作创建一个视图,你应该在 /Views/Home 文件夹下创建一个 About.cshtml 文件。

一个示例视图文件 ( About.cshtml ):

@{
ViewData["Title"] = "About";
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3> <p>Use this area to provide additional information.</p>

@ 符号代表 Razor 代码。 C# 语句在大括号( { } )包裹的 Razor 代码块中运行,就像上面展示的用 “About” 给 ViewData["Title"] 元素进行的赋值操作那样。Razor 可以通过简单地用 @ 符号对值进行引用从而在 HTML 里显示它们,就像上面 <h2><h3> 元素里面展示的那样。

这个视图只关心由它负责的这部分输出。而页面布局的其余部分,以及视图中的通用外观,则在别的地方指定。了解更多关于布局与共享视图逻辑

控制器如何指定视图?

视图通常作为一个ViewResult从操作中返回。你的操作方法可以直接返回一个 ViewResult ,但是更常见的是如果你的控制器是继承自Controller的,那么可以简单地使用 View 辅助方法,如下例所示:

HomeController.cs

public IActionResult About()
{
ViewData["Message"] = "Your application description page."; return View(); //手动高亮
}

这个 View 辅助方法有多个重载版本以便于帮助应用开发人员返回视图。你可以有选择性地指定一个返回的视图,还可以给视图传递一个模型对象。

当这个操作返回时,上面展示的 About.cshtml 视图将会被渲染:

视图发现

当操作返回视图的时,会进行一个叫做 视图发现 的过程。这个过程决定哪个视图文件将被采用。如果没有指定特定的视图文件,运行时首先会寻找与控制器对应的视图,然后再去 Shared 文件夹里寻找匹配的视图名称。

当操作返回 View 方法,就像 return View(); 这样,这个操作的名字则被用作视图名称。例如,假如这是从一个叫做 “ Index ” 的操作方法调用的,那么它就等价于传递了一个视图名称 “ Index ” 。也可以给这个方法传递一个明确的视图名称( return View("SomeView"); )。在这两种情况中,视图探寻都会在以下位置搜索匹配的视图文件:

  1. Views/<控制器名称>/<视图名称>.cshtml
  2. Views/Shared/<视图名称>.cshtml

我们推荐遵循约定,在可能的情况下简单地从操作中返回 View() ,这样会更加灵活,更易于重构代码。

可以提供视图文件路径,而非视图名。在这种情况下,.cshtml 扩展名必须作为文件路径的一部分明确指定。路径可以是相对于应用程序根目录的(可以选择性地以 “ / ” 或者 “ ~/ ” 开头)。例如: return View("Views/Home/About.cshtml");

局部视图以及视图组件采用了类似(但不完全一致)的发现机制。

你可以通过自定义的IViewLocationExpander来定制关于应用中的视图位于哪里的默认约定。

取决于基本文件系统,视图名称可能会区分大小写。为了跨系统的兼容性,应当总是保持控制器与操作名称同相关联的视图文件夹与文件名之间保持大小写一致。

给视图传递数据

你可以使用多种机制给视图传递数据。最健壮的方式就是在视图中指定一个 模型 类型(通常称为 视图模型 ,以区别于业务领域的模型类型 ),然后从操作中给视图传递一个该类型的实例。我们推荐你采用模型或视图模型给视图传递数据。这使得视图可以利用到强类型检查的优势。你可以通过 @model 指令为视图指定一个模型:

@model WebApplication1.ViewModels.Address // 手动高亮
<h2>Contact</h2>
<address>
@Model.Street<br />
@Model.City, @Model.State @Model.PostalCode<br />
<abbr title="Phone">P:</abbr>
425.555.0100
</address>

一旦为视图指定了模型,就可以像上面展示的那样,通过 @Model 以强类型的方式访问发送给视图的实例。为了给视图提供模型类型的实例,控制器将其作为参数传递进去:

public IActionResult Contact()
{
ViewData["Message"] = "Your contact page."; var viewModel = new Address()
{
Name = "Microsoft",
Street = "One Microsoft Way",
City = "Redmond",
State = "WA",
PostalCode = "98052-6399"
};
return View(viewModel); // 手动高亮
}

对于能够作为模型提供给视图的类型没有限制。我们推荐传递具有少量行为或者没有行为的普通旧 CLR 对象(Plain Old CLR Object,POCO)视图模型,这样就可以在应用的其他地方封装业务逻辑。这种方法的一个例子就是上面示例中的 Address 视图模型:

namespace WebApplication1.ViewModels
{
public class Address
{
public string Name { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
}
}

虽然你可以使用相同的类作为你的业务模型类型和显示模型类型。然而,将它们与你的领域或持久模型区分开来可以使视图独立地变化,并且还可以提供一些安全上的收益(对于那些用户通过 模型绑定发送给应用的模型)。

弱类型数据

除了强类型视图之外,所有的视图都可以访问弱类型的数据集合。这个集合可以通过控制器和视图的 ViewData 或者 ViewBag 属性来引用。ViewBag 属性是对 ViewData 的封装用以在集合上提供动态视图。它不是一个独立的集合。

ViewData 是一个通过 string 键访问的字典对象。你可以在里面储存和查询对象,并且在提取它们的时候无需转换成特定的类型。可以利用 ViewData 从控制器传递数据给视图,以及在视图之间(还有局部视图与布局)。字符串数据可以直接储存和使用,无需进行转换。

在操作中为 ViewData 设置一些值:

public IActionResult SomeAction()
{
ViewData["Greeting"] = "Hello";
ViewData["Address"] = new Address()
{
Name = "Steve",
Street = "123 Main St",
City = "Hudson",
State = "OH",
PostalCode = "44236"
}; return View();
}

在视图中使用数据:

    @{
// Requires cast
var address = ViewData["Address"] as Address; // 手动高亮
} @ViewData["Greeting"] World! // 手动高亮 <address>
@address.Name<br />
@address.Street<br />
@address.City, @address.State @address.PostalCode
</address>

ViewBag 对象为储存在 ViewData 里的对象提供动态访问。这样使用起来就更方便了,因为不需要转换。与上面的例子一样,在视图中采用了 ViewBag 而不是强类型的 Address 实例:

@ViewBag.Greeting World! // 手动高亮

<address>
@ViewBag.Address.Name<br /> // 手动高亮
@ViewBag.Address.Street<br /> // 手动高亮
@ViewBag.Address.City, @ViewBag.Address.State @ViewBag.Address.PostalCode // 手动高亮
</address>

由于二者引用的是相同的底层 ViewData 集合,在你读取和写入值的时候,可以根据方便与否来协调混用 ViewDataViewBag

动态视图

对于没有声明模型类型但给它们传递了模型实例的视图,可以动态地引用这个实例。例如,如果将一个 Address 实例传给了一个并没有声明 @model 的视图,那么这个视图还是能够像下面展示的那样去引用这个实例的属性:

<address>
@Model.Street<br />
@Model.City, @Model.State @Model.PostalCode<br />
<abbr title="Phone">P:</abbr>
425.555.0100
</address>

这种特性能提供一些灵活性,但无法提供编译保护和智能提示。如果属性并不存在,页面将在运行时出错。

更多视图特性

Tag helpers便于给已有的 HTML 标记添加服务端行为,不需要视图中的自定义代码或助手代码。Tag helper 是作为 HTML 元素的属性启用的,会被不认识它们的编辑器忽略掉,使得视图标签可以被很多的工具编辑和渲染。Tag helper 有很多用途,尤其是非常便于使用表单

可以用很多内置的HTML Helpers生成自定义的 HTML 标记,更复杂的 UI 逻辑(可能有它自己的数据需求)可以在 View Components中封装。与控制器和视图一样,视图组件也提供关注点分离,并且无需操作和视图就可以处理通用 UI 元素用到的数据。

与 ASP.NET Core 的很多方面一样,视图也支持依赖注入,允许将服务注入到视图

返回目录

ASP.NET Core 中文文档 第四章 MVC(3.1)视图概述的更多相关文章

  1. ASP.NET Core 中文文档 第四章 MVC(4.2)控制器操作的路由

    原文:Routing to Controller Actions 作者:Ryan Nowak.Rick Anderson 翻译:娄宇(Lyrics) 校对:何镇汐.姚阿勇(Dr.Yao) ASP.NE ...

  2. ASP.NET Core 中文文档 第四章 MVC(3.6.1 )Tag Helpers 介绍

    原文:Introduction to Tag Helpers 作者:Rick Anderson 翻译:刘浩杨 校对:高嵩(Jack) 什么是 Tag Helpers? Tag Helpers 提供了什 ...

  3. ASP.NET Core 中文文档 第四章 MVC(3.8)视图中的依赖注入

    原文:Dependency injection into views 作者:Steve Smith 翻译:姚阿勇(Dr.Yao) 校对:孟帅洋(书缘) ASP.NET Core 支持在视图中使用 依赖 ...

  4. ASP.NET Core 中文文档 第四章 MVC(4.6)Areas(区域)

    原文:Areas 作者:Dhananjay Kumar 和 Rick Anderson 翻译:耿晓亮(Blue) 校对:许登洋(Seay) Areas 是 ASP.NET MVC 用来将相关功能组织成 ...

  5. ASP.NET Core 中文文档 第四章 MVC(4.5)测试控制器逻辑

    原文: Testing Controller Logic 作者: Steve Smith 翻译: 姚阿勇(Dr.Yao) 校对: 高嵩(Jack) ASP.NET MVC 应用程序的控制器应当小巧并专 ...

  6. ASP.NET Core 中文文档 第四章 MVC(4.4)依赖注入和控制器

    原文: Dependency Injection and Controllers 作者: Steve Smith 翻译: 刘浩杨 校对: 孟帅洋(书缘) ASP.NET Core MVC 控制器应通过 ...

  7. ASP.NET Core 中文文档 第四章 MVC(4.1)Controllers, Actions 和 Action Results

    原文:Controllers, Actions, and Action Results 作者:Steve Smith 翻译:姚阿勇(Dr.Yao) 校对:许登洋(Seay) Action 和 acti ...

  8. ASP.NET Core 中文文档 第四章 MVC(3.9)视图组件

    作者: Rick Anderson 翻译: 娄宇(Lyrics) 校对: 高嵩 章节: 介绍视图组件 创建视图组件 调用视图组件 演练:创建一个简单的视图组件 附加的资源 查看或下载示例代码 介绍视图 ...

  9. ASP.NET Core 中文文档 第四章 MVC(3.7 )局部视图(partial)

    原文:Partial Views 作者:Steve Smith 翻译:张海龙(jiechen).刘怡(AlexLEWIS) 校对:许登洋(Seay).何镇汐.魏美娟(初见) ASP.NET Core ...

  10. ASP.NET Core 中文文档 第四章 MVC(01)ASP.NET Core MVC 概览

    原文:Overview of ASP.NET Core MVC 作者:Steve Smith 翻译:张海龙(jiechen) 校对:高嵩 ASP.NET Core MVC 是使用模型-视图-控制器(M ...

随机推荐

  1. 在离线环境中使用.NET Core

    在离线环境中使用.NET Core 0x00 写在开始 很早开始就对.NET Core比较关注,一改微软之前给人的印象,变得轻量.开源.跨平台.最近打算试着在工作中使用.但工作是在与互联网完全隔离的网 ...

  2. 使用python抓取婚恋网用户数据并用决策树生成自己择偶观

    最近在看<机器学习实战>的时候萌生了一个想法,自己去网上爬一些数据按照书上的方法处理一下,不仅可以加深自己对书本的理解,顺便还可以在github拉拉人气.刚好在看决策树这一章,书里面的理论 ...

  3. kafka学习笔记:知识点整理

    一.为什么需要消息系统 1.解耦: 允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束. 2.冗余: 消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险. ...

  4. vmware上网的方式

    vmware上网设置 vmware虚拟机上网设置 我的一些心得,如下: 如何使vmware虚拟机中的操作系统能够上网? 第一种情况: 主机使用PPPOE拨号上网 方法一:NAT方式 1.先关闭虚拟机中 ...

  5. 深入浅出Redis-redis哨兵集群

    1.Sentinel 哨兵 Sentinel(哨兵)是Redis 的高可用性解决方案:由一个或多个Sentinel 实例 组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所 ...

  6. AngularJS 系列 学习笔记 目录篇

    目录: AngularJS 系列 01 - HelloWorld和数据绑定 AngularJS 系列 02 - 模块 (持续更新)

  7. 1199 Problem B: 大小关系

    求有限集传递闭包的 Floyd Warshall 算法(矩阵实现) 其实就三重循环.zzuoj 1199 题 链接 http://acm.zzu.edu.cn:8000/problem.php?id= ...

  8. BZOJ 1103: [POI2007]大都市meg [DFS序 树状数组]

    1103: [POI2007]大都市meg Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2221  Solved: 1179[Submit][Sta ...

  9. WPF自定义控件第一 - 进度条控件

    本文主要针对WPF新手,高手可以直接忽略,更希望高手们能给出一些更好的实现思路. 前期一个小任务需要实现一个类似含步骤进度条的控件.虽然对于XAML的了解还不是足够深入,还是摸索着做了一个.这篇文章介 ...

  10. java运行时获得泛型类型

    引言 众所周知,java泛型最重要的特征是泛型擦除,所有泛型在编译时会转换成Object所以在java中运行时无法获得泛型的类型. 但是其实以上的规则是针对方法的内部变量的,如果是其他形式的泛型其实是 ...