为什么 Razor Pages 脚手架对索引、详细信息和删除页面使用 HTML 助手(而不是标签助手)?

Why does Razor Pages scaffolding use HTML Helpers (and not Tag Helpers) for Index, Details and Delete pages?

我最近使用 Razor Pages 开始了我的第一个项目,我正在使用 EF Core 并将我的所有模型搭建到 CRUD Razor Pages 中。我注意到生成的创建和编辑 Razor 页面使用 Tag Helpers 来显示数据。即

        <div class="form-group">
            <label asp-for="ViewModel.Name" class="control-label"></label>
            <input asp-for="ViewModel.Name" class="form-control" />
            <span asp-validation-for="ViewModel.Name" class="text-danger"></span>
        </div>

而索引、详细信息和删除页面使用 Html 助手来显示数据。即

    <dt>
        @Html.DisplayNameFor(model => model.ViewModel.Name)
    </dt>
    <dd>
        @Html.DisplayFor(model => model.ViewModel.Name)
    </dd>

Microsoft 的 link 表示 "Tag Helpers reduce the explicit transitions between HTML and C# in Razor views. In many cases, HTML Helpers provide an alternative approach to a specific Tag Helper, but it's important to recognize that Tag Helpers don't replace HTML Helpers and there's not a Tag Helper for each HTML Helper."。

但这些基本的显示字段当然可以使用 Tag Helpers 显示。在我看来,这似乎是一个相当轻浮的不一致,我认为最好的做法是主要使用 Tag Helpers 并且仅在绝对必要时才使用 Html Helpers。

我认为开发人员这样做是有原因的,但我不知道那是什么。谁能帮我解释一下吗?

简单:没有用于显示的标签助手。

展开:

为输入之类的东西设置标签助手很有意义:有特定的 HTML 标签与之关联。显示会变得更加模糊。每个开发人员可能希望使用不同的标签来显示:spanstrongthdt 等。这里没有一刀切的方法。您甚至可能根本不需要标签。默认情况下 Html.DisplayForHtml.DisplayNameFor 只输出值,没有任何标签。

此外,这些都是模板化的助手,这意味着您作为开发人员实际上可以将模板添加到 Views\Shared\DisplayTemplates 并自定义事物的显示方式。例如,您可以在 String.cshtml 视图中使用类似以下内容的内容:

@model string
<strong>@Model</strong>

现在,使用 Html.DisplayFor 显示的任何字符串 属性 都将包含在 strong 标签中。标签助手无法实现这种级别的自定义。

编辑

FWIW,如果你真的想使用标签助手,你可以添加自己的。例如:

public class DisplayNameTagHelper : TagHelper
{
    public ModelExpression For { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        output.TagName = "strong";
        output.Content.SetContent(For.Metadata.DisplayName);
    }
}

那么在你看来:

<display-name for="MyProperty" />

写一个 DisplayTagHelper 在概念上是相似的,但有点困难。您可以从 For.Model 中获取值。但是,这被键入为 object。使用 For.Metadata 上可用的信息,您需要确定您实际使用的是什么,并且可能有几个不同的分支来根据类型以不同方式显示内容。还有 For.Metadata.DataFormatString 需要考虑小数、日期时间等