在 ASP.NET Core MVC 中使用 Tag Helpers 有什么好处

What is the advantage of using Tag Helpers in ASP.NET Core MVC

我刚刚看到一篇关于名为 Tag helpers 的新 ASP.NET 核心功能的精彩文章。

从那里,我了解到可以替换以下代码:

@model MyProject.Models.Product

@using (Html.BeginForm())
{
    <div>
        @Html.LabelFor(m => p.Name, "Name:")
        @Html.TextBoxFor(m => p.Name)
    </div>
    <input type="submit" value="Create" />
}

与:

@model MyProject.Models.Product
@addtaghelper "Microsoft.AspNet.Mvc.TagHelpers"

<form asp-controller="Products" asp-action="Create" method="post">
    <div>
        <label asp-for="Name">Name:</label>
        <input asp-for="Name" />
    </div>

    <input type="submit" value="Save" />
</form>

有一些新语法,例如 asp-controllerasp-for 等。但是它有什么作用呢?这种新方法的优势是什么?

到目前为止我看到的最重要的改进是它保证对 HTML 元素的控制。虽然方便,但 MVC 使用的 Html 助手会在您尝试执行它们不是为之构建的事情时产生问题。

在MVC5中使用TextBox可以看到一个简单的例子:

 @Html.TextBoxFor(m => p.Name)

生成的 HTML 标记如下所示:

<input class="form-control" id="Name" name="Name" type="text" value="">

漂亮又简单。但是如果你想添加一个占位符属性呢?如果你想使用 bootstrap 的验证状态怎么办?如果您有一些需要自定义属性的第 3 方超酷 javascript 库怎么办? None 这些东西在 MVC5 的 初始版本 中是可能的。 尽管它们最终是以 [= 的形式通过更新添加的28=]html属性。即使现在添加自定义属性充其量也只是笨拙。

@Html.TextBoxFor(m => p.Name, 
    new {@class="form-control has-error", placeholder="Enter Name", 
    superCoolFeature="Do something cool"})

虽然您可能会争辩说这仍然是直接 HTML 中更少的代码,但它不再是一个重要的优势。更糟糕的是,该解决方案仍然没有涵盖相当常见的属性中的破折号。如果您需要它们,您会遇到诸如 ActionLink htmlAttributes

之类的解决方法

我已经尝试使用自定义编辑器修复这些缺陷,并尝试构建我自己的 TextBox 控件。很快就很明显,替换包含的 TextBox 模板需要大量工作。更糟糕的是,您的模板必须了解您要添加的任何扩展才能使用它们。

似乎将 Bootstrap 和其他第 3 方工具包含到 MVC 中使得当前设计在扩展 HTML 方面存在问题变得更加明显,需要修复。希望标签助手实现足够完整,以便我们将来可以避免使用它们。

我想到了一些事情:

  1. 正如@ChrisWalter 指出的那样,这些标签助手为 HTML 标签提供了 Open/Closed 质量。您不仅可以让您为常见的 HTML 模式编写扩展方法,还可以 扩展 一个 HTML 元素。这使您可以为每个组件挑选和混合多个扩展,而不必在它们之间进行选择。
  2. HTML 对于需要将内部 HTML 作为参数提供的元素,助手往往无法很好地工作。他们想出了一个巧妙的模式,所以你可以说:

    @using (Html.BeginForm(...)){
    {
        <input ... />
    }
    

    但是 BeginForm() 没有任何东西会强制您将其放在 using 语句中,也没有任何东西可以阻止您使用不正确的 HTML 结构。 (<input> 技术上 isn't allowed 直接位于 <form> 标签内。)

  3. 这为我们进入 HTML5 的 Web 组件世界提供了一个非常简单的过渡垫脚石。您今天编写的供 jQuery 或 Bootstrap 使用和增强的组件可能在几年后作为 Angular 2 或 Polymer 组件更有意义。使用 HTML 语法可以将 HTML 编写为 Web 组件时您希望它看起来的方式,并自动将其转换为现在(或特定的)必须采用的结构浏览器,稍后)。

更不用说,您的 Web Designers 将有真正的 HTML 标签可以编辑,他们可以识别这些标签以重新设计你的页面。设计师不应该成为编码员,这些敏锐的人足以跟上,研究 HTML5 和 CSS3 规范的移动目标。

接受的答案是正确的,但只是更正。 Html 帮助程序使用下划线覆盖属性中的破折号。例如,如果你想要 html 之类的 我的属性=值 然后你可以使用 html 助手,比如 @Html.TextBoxFor(m=>m.id, 新的 { my_attr = 值 }) 然后它会相应地转换。

我知道原来的问题问的是优点,但为了完整起见,我不得不提一个缺点

启用标签助手后,您无法在标签属性中注入 C# 代码。

即此代码将中断:

<!-- this won't work -->
<input class="@GetMyClass()">

<!-- this won't work too -->
<input type="checkbox" @(condition ? "checked" : "") >

要解决此问题,您可以使用自定义标签助手或完全禁用标签助手,如以下答案所述:

P.S。可以放心忽略我的拙见:标签助手是 "magic"。而"magic"在编程方面总是很糟糕。如果某物看起来像 HTML 标签,走路像标签,叫声也像标签 - 那么它应该是 HTML 标签。不知不觉"oh, it's not *really* a tag"。