ASP.NET Core 中的标记帮助程序

作者:Rick Anderson

什么是标记帮助程序

标记帮助程序使服务器端代码可以在 Razor 文件中参与创建和呈现 HTML 元素。 例如,内置 ImageTagHelper 可以将版本号追加到图像名称。 每当图像发生变化时,服务器都会为图像生成一个新的唯一版本,因此客户端总能获得当前图像(而不是过时的缓存图像)。 有多种常见任务(例如创建表单、链接,加载资产等)的内置标记帮助程序,公共 GitHub 存储库和 NuGet 包中甚至还有更多可用标记帮助程序。 标记帮助程序使用 C# 创建,基于元素名称、属性名称或父标记以 HTML 元素为目标。 例如,应用 LabelTagHelper 属性时,内置 LabelTagHelper 可以 HTML <label> 元素为目标。 如果你熟悉 Html 帮助器,标记帮助程序将减少视图中 HTML 和 c # 之间的显式转换 Razor 。 在很多情况下,HTML 帮助程序为特定标记帮助程序提供了一种替代方法,但标记帮助程序不会替代 HTML 帮助程序,且并非每个 HTML 帮助程序都有对应的标记帮助程序,认识到这点也很重要。 标记帮助程序与 HTML 帮助程序的比较更详细地介绍了两者之间的差异。

标记帮助程序的功能

HTML 友好的开发体验

大多数情况下, Razor 使用标记帮助程序的标记看起来像标准 HTML。 具有 HTML/CSS/JavaScript 的前端设计器熟悉可以在 Razor 不学习 c # 语法的情况下进行编辑 Razor 。

用于创建 HTML 和标记的丰富 IntelliSense 环境 Razor

与 HTML 帮助程序相比,这种方式与在视图中服务器端创建标记的方法相比,这种方法非常鲜明 Razor 。 标记帮助程序与 HTML 帮助程序的比较更详细地介绍了两者之间的差异。 标记帮助程序的 IntelliSense 支持解释了 IntelliSense 环境。 即使是经验丰富的开发人员, Razor 使用标记帮助程序也比编写 c # 标记更高效 Razor 。

使用仅在服务器上提供的信息,使您能够更高效、更可靠、更易于维护的代码。

例如,口头禅在更新映像时,更改映像时更改映像的名称。 出于性能原因,要主动缓存图像,而若不更改图像的名称,客户端就可能获得过时的副本。 以前,编辑完图像后,必须更改名称,而且需要更新 Web 应用中对该图像的每个引用。 这不仅非常耗费人力,而且还容易出错 (你可能会错过引用、意外输入错误的字符串等。 ) 内置 ImageTagHelper 可自动为你执行此操作。 ImageTagHelper 可将版本号追加到图像名称,这样每当图像出现更改时,服务器都会自动为该图像生成新的唯一版本。 客户端总是能获得最新图像。 使用 ImageTagHelper 实质上是免费获得稳健性而节省劳动力。

大多数内置标记帮助程序以标准 HTML 元素为目标,为该元素提供服务器端属性。 例如,<input> 用于包含 asp-for 特性的“视图/帐户”文件夹中的很多视图。 此特性将指定模型属性的名称提取至所呈现的 HTML。 请考虑 Razor 具有以下模型的视图:

public class Movie
{
    public int ID { get; set; }
    public string Title { get; set; }
    public DateTime ReleaseDate { get; set; }
    public string Genre { get; set; }
    public decimal Price { get; set; }
}

以下 Razor 标记:

<label asp-for="Movie.Title"></label>

则会生成以下 HTML:

<label for="Movie_Title">Title</label>

通过 LabelTagHelper 中的 For 属性,可使用 asp-for 特性。 请参阅创作标记帮助程序,获取详细信息。

管理标记帮助程序作用域

标记帮助程序作用域由 @addTagHelper@removeTagHelper 和“!”选择退出字符联合控制。

使用 @addTagHelper 添加标记帮助程序

如果创建名为 AuthoringTagHelpers 的新 ASP.NET Core Web 应用,将向项目添加以下 Views/_ViewImports.cshtml 文件:

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, AuthoringTagHelpers

@addTagHelper 指令让视图可以使用标记帮助程序。 在这种情况下,视图文件是 pages/_ViewImports,默认情况下,它由 pages 文件夹和子文件夹中的所有文件继承;使标记帮助程序可用。 上面的代码使用通配符语法 ( " * " ) 来指定指定程序集中的所有标记帮助器 (microsoft.aspnetcore.mvc.taghelpers) 将对 Views 目录或子目录中的每个视图文件可用。 @addTagHelper 后第一个参数指定要加载的标记帮助程序(我们使用“*”指定加载所有标记帮助程序),第二个参数“Microsoft.AspNetCore.Mvc.TagHelpers”指定包含标记帮助程序的程序集。 Microsoft.AspNetCore.Mvc.TagHelpers 是内置 ASP.NET Core 标记帮助程序的程序集。

要公开此项目中的所有标记帮助程序(将创建名为 AuthoringTagHelpers 的程序集),可使用以下内容:

@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, AuthoringTagHelpers

如果项目包含具有默认命名空间 (AuthoringTagHelpers.TagHelpers.EmailTagHelper) 的 EmailTagHelper,则可提供标记帮助程序的完全限定名称 (FQN):

@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper AuthoringTagHelpers.TagHelpers.EmailTagHelper, AuthoringTagHelpers

若要使用 FQN 将标记帮助程序添加到视图,请首先添加 FQN (AuthoringTagHelpers.TagHelpers.EmailTagHelper),然后添加程序集名称 (AuthoringTagHelpers)。 大多数开发人员更喜欢使用“*”通配符语法。 使用通配符语法,可在 FQN 中插入通配符“*”作为后缀。 例如,以下任何指令都将引入 EmailTagHelper

@addTagHelper AuthoringTagHelpers.TagHelpers.E*, AuthoringTagHelpers
@addTagHelper AuthoringTagHelpers.TagHelpers.Email*, AuthoringTagHelpers

如前文所述,将 @addTagHelper 指令添加到 views/_ViewImports cshtml 文件,使标记帮助程序可供 views 目录和子目录中的所有视图文件使用。 如果想选择仅对特定视图公开标记帮助程序,可在这些视图文件中使用 @addTagHelper 指令。

@removeTagHelper 删除标记帮助程序

@removeTagHelper@addTagHelper 具有相同的两个参数,它会删除之前添加的标记帮助程序。 例如,应用于特定视图的 @removeTagHelper 会删除该视图中的指定标记帮助程序。 在 Views/Folder/_ViewImports.cshtml 文件中使用 @removeTagHelper,将从 Folder 中的所有视图删除指定的标记帮助程序。

使用 _ViewImports.cshtml 文件控制标记帮助程序作用域

可将 _ViewImports.cshtml 添加到任何视图文件夹,视图引擎将同时应用该文件和 Views/_ViewImports.cshtml 文件中的指令。 如果为视图添加了空 views/ Home /_ViewImports cshtml 文件,则 Home 不会发生任何更改,因为 _ViewImports 的 cshtml 文件是附加的。 @addTagHelper添加到 views/ Home /_ViewImports (不在默认 Views/_ViewImports cshtml) 文件中的任何指令会将这些标记帮助程序公开给仅文件夹中的视图 Home

选择退出各个元素

使用标记帮助程序选择退出字符(“!”),可在元素级别禁用标记帮助程序。 例如,使用标记帮助程序选择退出字符在 <span> 中禁用 Email 验证:

<!span asp-validation-for="Email" class="text-danger"></!span>

须将标记帮助程序选择退出字符应用于开始和结束标记。 (将选择退出字符添加到开始标记时,Visual Studio 编辑器会自动为结束标记添加相应字符)。 添加选择退出字符后,元素和标记帮助程序属性不再以独特字体显示。

使用 @tagHelperPrefix 阐明标记帮助程序用途

@tagHelperPrefix 指令可指定一个标记前缀字符串,以启用标记帮助程序支持并阐明标记帮助程序用途。 例如,可以将以下标记添加到 Views/_ViewImports.cshtml 文件:

@tagHelperPrefix th:

在以下代码图像中,标记帮助程序前缀设置为 th:,所以只有使用前缀 th: 的元素才支持标记帮助程序(可使用标记帮助程序的元素以独特字体显示)。 <label><input> 元素具有标记帮助程序前缀,可使用标记帮助程序,而 <span> 元素则相反。

:: no (Razor) :::标记帮助程序前缀设置为 "th:" 的标记和输入元素名称

适用于 @addTagHelper 的层次结构规则也适用于 @tagHelperPrefix

自结束标记帮助程序

许多标记帮助程序都不能用作自结束标记。 某些标记帮助程序被设计为自结束标记。 使用未被设计为自结束的标记帮助程序会抑制呈现的输出。 自结束标记帮助程序会在呈现的输出中生成自结束标记。 有关详细信息,请在创作标记帮助程序中查看此问题

标记帮助程序属性/声明中的 C#

标记帮助程序不允许在元素的属性或标记声明区域中出现 C#。 例如,以下代码是无效的:

<input asp-for="LastName"  
       @(Model?.LicenseId == null ? "disabled" : string.Empty) />

前面的代码可以编写为:

<input asp-for="LastName" 
       disabled="@(Model?.LicenseId == null)" />

标记帮助程序的 Intellisense 支持

当你在 Visual Studio 中创建新的 ASP.NET Core web 应用时,它会将 NuGet 包添加到 "AspNetCore Razor "。工具 "。 这是添加标记帮助程序工具的包。

请考虑编写 HTML <label> 元素。 只要在 Visual Studio 编辑器中输入 <l,IntelliSense 就会显示匹配的元素:

在键盘上键入 "l" 后,IntelliSense 会建议一个列表,其中包含选定了 "标签" 的可能的标记名称。

不仅会获得 HTML 帮助,还会有图标(下方带有“<>”的“@" symbol with ")

@" symbol with "它下面的 "<>"。

图标将元素标识为标记帮助器的目标元素。 纯 HTML 元素(如 fieldset)显示“<>”图标。

纯 HTML <label> 标记以棕色字体显示 HTML 标记(使用默认 Visual Studio 颜色主题时),以红色字体显示属性,并以蓝色字体显示属性值。

示例 "标签" HTMl 标记

输入 <label 后,IntelliSense 会列出可用的 HTML/CSS 属性和以标记帮助程序为目标的属性:

用户键入了一个开始方括号和 HTML 元素名称"label"。 IntelliSense 显示可能的属性列表, (未预先选择任何) 。

通过 IntelliSense 语句完成功能,按 Tab 键即可用选择的值完成语句:

用户键入了一个开始方括号,即 HTML 元素名称"label",并开始键入属性名称 ("as") 。 IntelliSense 会显示一个对话框,其中选择了"asp-for"。

只要输入标记帮助程序属性,标记和属性字体就会更改。 如果使用默认的 Visual Studio“蓝色”或“浅色”颜色主题,则字体是粗体紫色。 如果使用“深色”主题,则字体为粗体青色。 本文档中的图像在使用默认主题时截取的。

用户选择了"asp-for",它现在以粗体紫色显示,因为该用户没有使用深色主题。

可在双引号 ("") 内输入 Visual Studio CompleteWord 快捷方式(默认值为 Ctrl+空格键),即可使用 C#,就像在 C# 类中一样。 IntelliSense 会显示页面模型上的所有方法和属性。 由于属性类型是 ModelExpression,所以这些方法和属性可用。 在下图中,我正在编辑 Register 视图,所以 RegisterViewModel 是可用的。

用户在"asp-for"属性的值中输入"e"。 IntelliSense 建议在完成时选择"电子邮件"。

IntelliSense 会列出页面上模型可用的属性和方法。 丰富 IntelliSense 环境可帮助选择 CSS 类:

用户通过类型"cl"将属性添加到"input"元素。 IntelliSense 提供已选择"类"的完成建议列表。

用户类型"co"作为"input"元素的"class"属性的值。 IntelliSense 提供选择了"col"的完成建议列表。

标记帮助程序与 HTML 帮助程序的比较

标记帮助程序附加到视图中的 HTML 元素,而 HTML 帮助程序被调用为与视图中 Razor HTML 交错 Razor 的方法。 请考虑以下 Razor 标记,该标记使用 CSS 类"caption"创建 HTML 标签:

@Html.Label("FirstName", "First Name:", new {@class="caption"})

位于 () @ 符号 Razor 指示这是代码的开始。 接下来的两个参数(“FirstName”和“First Name:”)是字符串,所以 IntelliSense 无法提供帮助。 最后一个参数:

new {@class="caption"}

是用于表示属性的匿名对象。 由于 class 是 C# 中的保留关键字,因此要使用 @ 符号强制 C# 将 @class= 解释为符号(属性名称)。 对于前端设计器 (熟悉 HTML/CSS/JavaScript 和其他客户端技术,但不熟悉 C# Razor 和) ,大部分行都是外行。 必须在没有 IntelliSense 帮助的情况下编写整行代码。

使用 LabelTagHelper,相同标记可以编写为:

<label class="caption" asp-for="FirstName"></label>

使用标记帮助程序版本,只要在 Visual Studio 编辑器中输入 <l,IntelliSense 就会显示匹配的元素:

用户在键盘上键入"l"。 IntelliSense 建议 HTML 元素完成,并选中"标签"。

IntelliSense 可帮助编写整行。

下面的代码图显示了从 Visual Studio 中包含的 ASP.NET 4.5.x MVC 模板生成的 Views/Account/Register.cshtml 视图的 Form Razor Visual Studio。

Register :::no-loc (Razor) ::: Register ::no-loc (Razor) ::: view for ASP.NET 4.5 MVC 项目模板的窗体部分标记

Visual Studio 编辑器以灰色背景显示 C# 代码。 例如,AntiForgeryToken HTML 帮助程序:

@Html.AntiForgeryToken()

以灰色背景显示。 Register 视图中的标记大部分是 C#。 将其与使用标记帮助程序的等效方法进行比较:

Register :::no-loc (Razor) ::: 标记帮助程序标记的标记,用于注册 :::no-loc (Razor) ::: 视图的 ASP.NET Core 项目模板

与 HTML 帮助程序方法相比,此标记更清晰,更容易阅读、编辑和维护。 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# 模型表达式属性。

Visual Studio 编辑器可帮助编写注册窗体的标记帮助程序方法中的所有标记,而 Visual Studio 不会为 HTML 帮助程序方法中的大多数代码提供帮助。 标记帮助程序的 IntelliSense 支持详细介绍了如何在 Visual Studio 编辑器中使用标记帮助程序。

标记帮助程序与 Web 服务器控件的比较

  • 标记帮助程序不拥有与其相关的元素:它们只是参与元素和内容的呈现。 ASP.NETWeb 服务器控件在页面上声明和调用。

  • ASP.NETWeb 服务器控件具有一个非普通生命周期,这会使开发与调试更加困难。

  • 通过 Web 服务器控件,可使用客户端控件向客户端文档对象模型 (DOM) 元素添加功能。 标记帮助程序没有 DOM。

  • Web 服务器控件包括自动浏览器检测。 标记帮助程序不了解浏览器。

  • 通常不能撰写 Web 服务器控件时,多个标记帮助程序可作用于同一元素(请参阅避免标记帮助程序冲突)。

  • 标记帮助程序可以修改其作用域内 HTML 元素的标记和内容,但不会直接修改页面上的其他内容。 Web 服务器控件的作用域较广,并且可以执行影响页面其他部分的操作,从而可能造成意想不到的副作用。

  • Web 服务器控件使用类型转换器将字符串转换为对象。 使用标记帮助程序时,本身就用 C# 语言工作,因此无需进行类型转换。

  • Web 服务器控件使用 System.ComponentModel 实现组件和控件的运行时和设计时行为。 System.ComponentModel 包括用于属性和类型转换器的实现、数据源绑定和组件授权的基类和接口。 与通常派生自 TagHelper 的标记帮助程序相比,TagHelper 基类仅公开两个方法,即 ProcessProcessAsync

自定义标记帮助程序元素字体

可以从"工具""选项""环境字体和颜色" > > > 自定义字体和着色

"选项"对话框Visual Studio

内置 ASP.NET Core 标记帮助程序

定位点标记帮助程序

缓存标记帮助程序

组件标记帮助程序

分布式缓存帮助程序

环境标记帮助程序

表单标记帮助程序

窗体操作标记帮助程序

图像标记帮助程序

输入标记帮助程序

标签标记帮助程序

链接标记帮助程序

分部标记帮助程序

脚本标记帮助程序

选择标记帮助程序

文本区标记帮助程序

验证消息标记帮助程序

验证摘要标记帮助程序

其他资源