覆盖 DisplayNameFor() 的默认约定

Override default convention for DisplayNameFor()

我有很多 属性 名称采用 PascalCase 命名。

例如:

public string ProposalNotes { get; set; }

我在覆盖默认 Html.DisplayNameFor() 方法后自动将 属性 名称拆分为 "Proposal Notes",而无需添加显示属性,如下所示:

[Display(Name = "Proposal Notes")]

我希望 DisplayName 属性在需要覆盖此新约定时仍然有效。例如,当我有 属性 个名字时,例如 "PgCodeInst" 到 "Institution Code"。

有什么办法吗?

我记得有一个关于如何做类似事情但找不到的教程。

这当然是可能的,但我只是对源代码进行了一些挖掘,我认为你会发现它带来的麻烦远远超过它的价值。有多个 类 您必须从中派生并覆盖方法,然后您必须连接所有自定义内容来代替 built-ins.

添加 Display 属性并没有那么大的负担,坦率地说,其意图更加明确,这总是一件好事。但是,如果您 dead-set 反对使用它,您可以考虑使用像 Humanizer 这样的库,然后做一些类似的事情:

@nameof(Model.ProposalNotes).Titleize();

FWIW,您需要将 using 语句添加到您的视图 (@using Humanizer),但您可以在 _ViewImports.cshtml.

中只执行一次

此外,根据您实际想要显示名称的目的,您始终可以创建一个 custom tag helper. For example, to automatically do this with labels, you can simply inherit from LabelTagHelper(或创建您自己的)并使用您自己的自定义用于确定要在 那里显示 的显示名称的逻辑,而不用担心更改 DisplayNameFor 等内容的行为。您还可以创建一个自定义标签助手来只输出上面的标题名称:

public class TitleizeTagHelper : TagHelper
{
    const string ForAttributeName = "asp-for";

    [HtmlAttributeName(ForAttributeName)]
    public ModelExpression For { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        output.TagName = "span";
        output.SetContent(For.Name.Titleize());
    }
}

然后:

<titleize asp-for="ProposalNotes" />

无可否认,对于如此简单的事情来说,这有点矫枉过正,但如果实际应用了该属性,您也可以通过窃取 LabelTagHelper 的逻辑来支持自定义显示名称来加强它。