原文:Introduction to Tag Helpers
作者:Rick Anderson
翻译:刘浩杨
校对:高嵩(Jack)
- 什么是 Tag Helpers?
- Tag Helpers 提供了什么
- 管理 Tag Helper 范围
- Tag Helpers 智能感知支持
- Tag Helpers 和 HTML Helpers 比较
- Tag Helpers 和 Web 服务器控件比较
- 自定义 Tag Helper 元素字体
- 附加资源
什么是 Tag Helpers ?
在 Razor 文件中,Tag Helpers 能够让服务端代码参与创建和渲染 HTML 元素。例如,内置的ImageTagHelper能够在图像名称后面追加版本号。每当图像变化时,服务器为图像生成一个新的唯一的版本,因此保证客户端得到当前图像(而不是旧的缓存图像)。对于常见任务有许多内置的 Tag Helpers - 比如创建表单,链接,加载资产以及更多 - 在公共的 Github 存储库中的和以 NuGet 包的方式存在的可用资源。在 C# 里编写 Tag Helpers,它们的目标是基于元素名称,特性名称或者父标签的 HTML 元素。例如,当 LabelTagHelper
特性被应用时,内置的LabelTagHelper能够作用于 HTML <label>
元素。如果你熟悉 HTML Helpers,Tag Helpers 在 Razor 视图中减少 HTML 和 C# 之间的显示转换。 Tag Helpers 和 HTML Helpers 比较 解释了更详细的差异。
Tag Helpers 提供了什么
一种 HTML-friendly 的开发体验
在大多数情况下,Razor 标记使用 Tag Helpers 看起来更像标准的 HTML。熟悉 HTML/CSS/JavaScript 的前端设计师在没有学习 C# Razor 语法的情况下能够编辑 Razor 。
一个丰富的智能感知环境来创建 HTML 和 Razor 标记
这和 HTML Helpers 有明显的对比,前一种方法在服务端创建 Razor 视图中的标记。 Tag Helpers 和 HTML Helpers 比较 讲解了更详细的差异。Tag Helpers 智能感知支持 讲解了智能感知环境。
一种使用仅在服务器上可用的信息让你更高效并且能够生成更强大,可靠和可维护代码的方式
例如,在之前当你更改图像的时候,更新图像的原则是更改图像的名称。出于性能原因应该主动缓存图像,除非你改变图像的名称,你的客户端有得到一份过期的副本的风险。在之前,一个图像被编辑后,它的名称必须改变并且在网络应用程序中图像的每一个引用都需要更新。这不仅是体力活,同时也容易出错(你可能漏掉一个引用,意外的输入错误字符串等)。内置的 ImageTagHelper能够自动为你做这件事情。ImageTagHelper
能够在图像名称后追加一个版本号,每当图像变化时,服务器为图像自动生成一个新的唯一的版本。客户端被保证得到当前的图像。通过使用 ImageTagHelper
这种健壮性和节省劳力基本上是无偿的。
大多数内置的 Tag Helpers 指向现有的 HTML 元素并且为这些元素提供服务端特性。例如:在 Views/Account 文件夹下的许多视图中使用的 <input>
元素包含了 asp-for
属性,提取指定模型的属性名称到呈现的 HTML 中。Razor 标记如下:
<label asp-for="Email"></label>
生成以下的 HTML :
<label for="Email">Email</label>
asp-for
特性由在 LabelTagHelper
中的 For
属性提供。查看 :doc:authoring
获取更多信息。
管理 Tag Helper 范围
Tag Helpers 的范围由 @addTagHelper
和 @removeTagHelper
进行控制,并且 "!" 为退出字符。
@addTagHelper
使 Tag Helpers 可用
如果你创建一个新的 ASP.NET Core web 应用,命名为 AuthoringTagHelpers (无身份认证),下面的 Views/_ViewImports.cshtml 文件将被添加到你的项目:
@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers // 手动高亮
@addTagHelper
指令使 Tag Helpers 在视图中可用。在这种情况下,视图文件是 Views/_ViewImports.cshtml ,默认继承所有的在 Views 和子目录中的视图文件;使 Tag Helpers 可用。上面的代码使用通配符 ("") 来指定在特定程序集(Microsoft.AspNetCore.Mvc.TagHelpers)中的所有的 Tag Helpers 在每一个 Views 目录和子目录中的视图文件中可用。 @addTagHelper
后面的第一个参数指定要加载的 Tag Helpers (对于所有 Tag Helpers,我们使用 “”),第二个参数 “Microsoft.AspNetCore.Mvc.TagHelpers” 指定包含 Tag Helpers 的程序集。 Microsoft.AspNetCore.Mvc.TagHelpers 是内置的 ASP.NET Core Tag Helpers 程序集。
这个项目中,为了暴露所有的Tag Helpers(创建一个名称为 AuthoringTagHelpers 的程序集),你可以像下面一样使用:
@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper "*, AuthoringTagHelpers" // 手动高亮
如果你的项目包含一个使用默认命名空间(AuthoringTagHelpers.TagHelpers.EmailTagHelper
)的 EmailTagHelper
,你可以对 Tag Helper 提供完全限定名(FQN):
@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper "AuthoringTagHelpers.TagHelpers.EmailTagHelper, AuthoringTagHelpers" // 手动高亮
为了使用 FQN 在视图中添加一个 Tag Helper,你首先添加 FQN (AuthoringTagHelpers.TagHelpers.EmailTagHelper
),然后是程序集名称(AuthoringTagHelpers)。大多数开发者喜欢使用 "*" 通配符语法。通配符语法允许你在 FQN 中插入通配符 "*" 作为后缀。例如,下列指令将在 EmailTagHelper
中引入:
@addTagHelper "AuthoringTagHelpers.TagHelpers.E*, AuthoringTagHelpers"
@addTagHelper "AuthoringTagHelpers.TagHelpers.Email*, AuthoringTagHelpers"
像前面说的,添加 @addTagHelper
指令到 Views/_ViewImports.cshtml 文件使 Tag Helper 可用于 Views 目录和子目录中的所有视图文件。如果你想选择在特定的视图文件中暴露 Tag Helper ,你可以在这些视图文件中使用 @addTagHelper
指令。
@removeTagHelper
删除 Tag Helpers
@removeTagHelper
具有和 @addTagHelper
相同的两个参数,并且它删除之前添加的一个 Tag Helper 。例如: @removeTagHelper
应用于从特定的视图中移除特定的 Tag Helper 。在 Views/Folder/_ViewImports.cshtml 中使用 @removeTagHelper
删除 Folder 中所有视图中特定的 Tag Helper 。
在 _ViewImports.cshtml 中控制 Tag Helper 的范围
你可以在任何视图文件夹中添加一个 _ViewImports.cshtml ,并且视图引擎添加 _ViewImports.cshtml 文件中的指令到包含它们的 Views/_ViewImports.cshtml 文件中。如果你为 Home 视图添加一个空 Views/Home/_ViewImports.cshtml 文件,它们不会有任何变化因为 _ViewImports.cshtml 文件是追加的。你添加到 Views/Home/_ViewImports.cshtml 文件(不是默认的 Views/_ViewImports.cshtml 文件)的任何 @addTagHelper
指令将会只在 Home 文件夹中公开这些 Tag Helpers 。
禁用个别元素
你可以在元素级别禁用带有退出符("!")的标签助手。例如:在 <span>
中带有退出字符的 Email
验证被禁用:
<!span asp-validation-for="Email" class="text-danger"></!span>
你必须使用 Tag Helper 退出字符来打开和关闭标签。(当你添加一个打开标签时, Visual Studio 编辑器自动添加退出字符来关闭标签)。在你添加退出字符之后,元素和 Tag Helper 特性将不再以特殊的字体显示。
使用 @tagHelperPrefix
让 Tag Helper 用法明确
@tagHelperPrefix
指令允许你指定一个标签前缀来启用 Tag Helper 支持和使 Tag Helper 用法明确。在下面的代码图片中,Tag Helper 前缀设置为 th:
,因此只有那些使用前缀 th:
的元素支持 Tag Helpers (Tag Helper可用的元素有独特的字体)。 <label>
和 <input>
元素使用 Tag Helper 前缀并且 Tag Helper 可用, <span>
元素不能使用 Tag Helper。
同一层次的规则适用于 @addTagHelper
也适用于 @tagHelperPrefix
。
Tag Helpers 智能感知支持
当你在 Visual Studio 中创建一个新的 ASP.NET web 应用,在 project.json 文件中添加 "Microsoft.AspNetCore.Razor.Tools" 。这是添加 Tag Helper 工具的包。
考虑写一个 HTML <label>
元素。在 Visual Studio 编辑器中你一进入 <l
,智能感知显示匹配的元素:
你得到的不仅仅是 HTML 的帮助,而且图标(下面含有“<>” 的“@”符号)。
有针对性的通过 Tag Helpers 标识元素。纯 HTML 元素(如 fieldset
)显示 "<>" 图标。
一个纯 HTML <label>
标签使用棕色字体显示 HTML 标签(默认的 Visual Studio 颜色主题),特性使用红色,特性值使用蓝色。
在你输入 <label
后,智能感知列出可用的 HTML/CSS 特性和 Tag Helper 目标特性:
智能感知语句完成允许你输入 tab 键来完成所选值的语句:
一旦你输入了一个 Tag Helper 特性,标签和属性的字体改变。使用 Visual Studio 默认的 "Blue" 或 "Light" 颜色主题,字体是醒目的紫色。如果你使用 "Dark" 主题,字体是醒目的蓝绿色。在这个文档中的图片使用的是默认的主题。
你可以在双引号("")里输入 Visual Studio 的 CompleteWord 快捷键( 默认的 是 Ctrl +spacebar ),你现在在 C# 中,就像你在一个 C# 类中。智能感知显示页面模型的所有方法和属性。方法和属性能被使用因为属性类型是 ModelExpression
。在下面的图片中,我编辑 Register
视图,所以 RegisterViewModel
是可用的。
智能感知列出模型在页面上可用的属性和方法。丰富的智能感知环境帮助你选择 CSS class:
Tag Helpers 和 HTML Helpers 比较
Tag Helpers 在 Razor 视图中附加到 HTML 元素,而 `HTML Helpers 在 Razor 视图中作为穿插到 HTML 的方法被调用。考虑下面的 Razor 标记,它创建一个带有 "caption" CSS class的HTML label 标签:
@Html.Label("FirstName", "First Name:", new {@class="caption"})
at (@
) 符号告诉 Razor 这是代码的开始。接下来的两个参数("FirstName" 和 "First Name:")是字符串,所以 `IntelliSense 不能帮助。最后的参数:
new {@class="caption"}
是一个用于表示特性的匿名对象。因为 class 是一个 C# 的保留关键字,使用 @
符号强制 C# 解释 "@class=" 作为一个符号(属性名称)。对于一个前端设计师(一些人熟悉 HTML/CSS/JavaScript 和其他客户端技术但是不熟悉 C# 和 Razor)来讲,该行的大部分是陌生的。整行必须在没有智能感知的帮助下编写。
使用 LabelTagHelper
,相同的标记可以被写为:
使用 Tag Helper 的版本,一旦你在 Visual Studio 编辑器输入 <l
,智能感知显示匹配的元素:
智能感知帮助你写整行代码。 LabelTagHelper
也默认设置 asp-for
特性值("FirstName")的内容到 "First Name";它转换驼峰名称属性到由每一个首字母大写的属性名称组成的句子。在下面的标记中:
生成:
<label class="caption" for="FirstName">First Name</label>
如果你想添加内容到 <label>
中,camel-cased 到 sentence-cased 的内容不被使用。例如:
生成:
<label class="caption" for="FirstName">Name First</label>
下面的代码图片展示了从传统的包含在 Visual Studio 2015 中的 ASP.NET 4.5.x MVC 的模版生成的 Views/Account/Register.cshtml Razor 视图的表单部分。
Visual Studio 编辑器使用灰色背景显示 C# 代码。例如, AntiForgeryToken
HTML Helper:
@Html.AntiForgeryToken()
被灰色背景显示。在 Register 视图中大部分标记是 C#。与使用 Tag Helpers 的等效方法比较:
和 HTML Helpers 方法相比,这些标记干净的多并且更容易阅读,编辑和维护。C# 代码减少到服务器需要知道的最小值。 Visual Studio 编辑器通过一个独特的字体显示标记的目标。
考虑 Email 组:
<div class="form-group">
<label asp-for="Email" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
</div>
每一个 "asp-" 特性都有一个 "Email" 值,但是 "Email" 不是字符串。在这个上下文, "Email" 是对于 RegisterViewModel
的 C# 模型表达式属性。
使用Tag Helper 注册表单中的方法,Visual Studio 编辑器会帮助你编写 所有 标记,而Visual Studio 没有给 HTML Helpers 方法的代码提供帮助 IntelliSense support for Tag Helpers
_ 详细介绍 Tag Helpers 在 Visual Studio 编辑器中的工作。
Tag Helpers 和 Web 服务器控件比较
-
Tag Helpers 不拥有它们所关联的元素,它们只简单的参与元素和内容的渲染。ASP.NETWeb Server controls声明并且在页面上调用。
-
`Web 服务器控件有一个不一样的生命周期使得开发和调试困难。
-
Web 服务器控件允许你给通过客户端控件给客户端文档对象模型(ocument Object Model ,DOM)添加功能。Tag Helpers 不具有 DOM。
-
Web 服务器控件包含自动的浏览器检测。 Tag Helpers 不能识别浏览器。
-
多个 Tag Helpers 可以作用在相同的元素,而你通常不能构成 Web 服务器控件。
-
Tag Helpers 可以修改在它们范围内的标签和 HTML 元素的内容,但是不直接修改页面上的任何内容。 Web 服务器控件有一个较小的特定范围,可以执行影响页面其他部分的操作,从而造成非预期的副作用。
-
Web 服务器控件使用类型转换器(type converters)转换字符串到对象。使用 Tag Helpers,你本身就使用 C# 工作,所以你不需要做类型转换。
-
Web 服务器控件使用 System.ComponentModel实现组件和控件的运行时和设计时行为。
System.ComponentModel
包括用于实现属性和类型转换器的基类和接口,绑定到数据源和授权组件。和 Tag Helpers 对比,通常来自TagHelper
,并且TagHelper
基类只公开两个方法Process
和ProcessAsync
。
自定义 Tag Helper 元素字体
你可以在 工具 > 选项 > 环境 > 字体和颜色 中自定义字体和颜色:
附加资源
- Authoring Tag Helpers
- Working with Forms (Tag Helpers)
- TagHelperSamples on GitHub包含与 Bootstrap一起工作的 Tag Helper 示例。