65.9K
CodeProject 正在变化。 阅读更多。
Home

TagHelpers

2014 年 12 月 16 日

CPOL

11分钟阅读

viewsIcon

35240

本文讨论了 TagHelpers - ASP.NET vNext 中新增的一项功能。

引言

TagHelper 是 ASP.NET MVC 中的一项新功能。如果您还没有听说过,TagHelpers 已经在技术圈中引起了广泛的讨论,有些人声称这是服务器端控件的回归。有人还记得吗?

<asp:TextBox id="txt1" runat="server">

我个人认为 TagHelpers 没有问题,它只是在混合 HTML 和服务器生成内容方面的一种简化,而没有控件生命周期、视图状态、事件等方面的负担。事实上,我认为它是一种更简洁的方法。

免责声明

本文基于 ASP.NET 5(或 vNext)的 beta 版本。情况可能会也一定会发生变化,因此关于 TagHelpers 的一些信息可能已过时。

目的

已经有关于 TagHelpers 的文章了——其中一些非常出色的文章出自 Scott HanselmanJeffrey T. Fritz(参见资源)。本文在此基础上进一步扩展,因为

  1. 它提供了基于最新开发版本(v1.0.0-rc1-10798)的更及时信息。
  2. 它提供了面向开发者的 TagHelpers 视角,包含更多示例。
  3. 我们通过构建一个示例项目来介绍。我花了些时间才弄清楚各个部分是如何组合在一起的,因为一切都在不断变化,而且文档又不完善,所以这可能会为其他人节省时间。

什么是 TagHelpers?

TagHelpers 允许使用服务器端内容对 HTML 属性进行预处理——也就是说,

<a asp-controller="Home" asp-action="About">About</a>

被转换为

<a href="/Home/About">About</a>

在深入研究之前,让我们先看看当前版本的 MVC 的行为。这将让我们体会到 TagHelpers 的必要性。

在 ASP.NET MVC 5 中,如果我们想声明一个指向另一个页面的链接(anchor 标签),有几种选择。

ActionLink

也许最常见的是使用 HTML 辅助函数 `ActionLink` 方法。有几种重载,我使用的是允许我设置操作、控制器和 HTML 属性的那种。

public static MvcHtmlString ActionLink(
        this HtmlHelper htmlHelper,
        string linkText,
        string actionName,
        string controllerName,
        Object routeValues,
        Object htmlAttributes
)

简单的用法如下:

@Html.ActionLink("About this site",
"About","Home",null,new { @class="someClass"})

Razor & HTML

另一种选择是在 Razor 语法中进行混合搭配。

<a href="@Url.Action("About", 
"Home")" class="someClass">About this site</a>

我们也可以创建自己的 Razor 辅助函数或 HTML 辅助函数扩展方法。

虽然这不算坏,但我们的场景很简单,我相信我们都知道将 Razor 语法与 HTML 混合搭配是多么棘手。另一种看待这个问题的方式是,在第一个例子中,我们首先使用了 Razor,然后添加了 HTML 属性,而在第二个例子中,我们首先使用了 HTML,然后添加了 Razor 语法。

AnchorTagHelper

这就是 TagHelper 发挥作用的地方,因为我们不必离开 HTML 的舒适区,同时又能利用 C# 服务器端的强大功能。考虑到上面的相同示例,我们可以重写 anchor 标签为:

<a asp-controller="Home" asp-action="About" class="someClass">About this site</a>

为了简化接下来的过程——MVC 将这个 anchor 传递给一个 C# 类(`AnchorTagHelper`),该类会检查属性并输出服务器生成的 C# 代码。这是混合 HTML 和 C# 代码的一种更简洁的方式。

这与 ASP.NET 服务器端控件不同,尽管语法/概念可能看起来非常相似。主要区别在于:

  • 无生命周期事件
  • 无视图状态
  • 无控件状态

注意:有些文章会提到控制器和操作属性的使用。然而,关于这个问题有一个 讨论,看起来在三种流行的方法中,以 `asp-` 作为前缀的方法已被选定在当前版本中。另外两种选择是使用 `@controller` 或直接使用 `controller`。

TagHelpers 命名空间

ASP.NET 已自带一组内置的 TagHelpers。它们位于 `Microsoft.AspNet.Mvc.TagHelpers` 命名空间中,包括:

  • Anchor
  • 输入
  • Label
  • Select
  • TextArea
  • ValidationMessage
  • ValidationSummary
  • 表单

我们将快速了解所有这些以及它们的基本用法。

AnchorTagHelper

此标签将应用于 `` 锚点元素。目前,它支持以下属性:

  1. asp-action
  2. asp-controller
  3. asp-fragment
  4. asp-host
  5. asp-protocol
  6. asp-route

所有这些都用于为 `` 锚点标签的 `href` 属性生成 URL。

<a asp-controller="Home" asp-action="About">About</a>

如果 `href` 已经在 `` 锚点 HTML 元素中设置,并且设置了 TagHelper 属性,则会抛出异常。因此,例如,下面的代码将抛出异常:

<a href="/Home/Index" asp-controller="Home" asp-action="Index">Home</a>

InputTagHelper

顾名思义,此 `TagHelper` 应用于 `` HTML 元素。它类似于 `TextBoxFor` HTML 扩展方法,因为它会生成一个绑定到模型属性的输入元素。`input` 标签支持以下属性:

  1. asp-for
  2. asp-format

`'asp-for'` 属性引用模型中的属性,并且也用于各种其他 TagHelper。

`'asp-format'` 在检索值后应用格式。这对于货币或日期时间值很有用。例如(`Birthday` 是模型中 `DateTime` 类型的属性)。

<input asp-for="Birthday" asp-format="{0:yyyy-MM-dd}" />

注意:`asp-for` 的类型是 `ModelExpression`,这是 ASP.NET MVC 6 (vNext) 中的一个新类。构造函数接受一个 `string` 参数,该参数会计算为模型中的一个属性。我们还可以引用嵌套对象——例如:

<input asp-for="Address.Street" type="text" /></div>

与 `TextBoxFor` 对比:

@Html.TextBoxFor(model => model.Birthday)

目前,MVC 6 模型绑定器存在一个问题,输入无效日期(`abc`)会显示一个异常消息。

从类型 '`System.String`' 到类型 '`System.DateTime`' 的参数转换失败。请参阅内部异常以获取更多信息。

在 MVC 5 中,异常消息被重新处理成一个更友好的版本,如:

The value 'abc' is not valid for Birthday

LabelTagHelper

与 `HtmlExtension.LabelFor` 方法具有相同的目的——只有一个属性 `'asp-for'`,用于定义模型中的属性(如 `InputTagHelper` 中所述)。它应用于 `

<label asp-for="Birthday" />

SelectTagHelper

`SelectTagHelper` 应用于 `