Override default convention for DisplayNameFor()

451 views Asked by At

I have lots of property names with PascalCase names.

For example:

public string ProposalNotes { get; set; }

I am after overriding the default Html.DisplayNameFor() method to automatically split the property names to "Proposal Notes" without having to add the display attributes as below:

[Display(Name = "Proposal Notes")]

I want the DisplayName attributes to still work when I need to override this new convention. For example when I have property names like "PgCodeInst" to "Institution Code".

Is there any way of doing this?

I remember a tutorial on how to do something similar but cannot find it.

1

There are 1 answers

1
Chris Pratt On BEST ANSWER

It's certainly possible, but I just went digging through the source a bit, and I think you're going to find it far more trouble than it's worth. There's multiple classes you'd have to derive from and override methods on, and then you'd have to wire in all your custom stuff in place of the built-ins.

Adding the Display attribute is not really all that much of a burden, and frankly is a bit more explicit in its intention, which is always a good thing. However, if you're dead-set against using it, you might instead consider using a library like Humanizer and just doing something like:

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

FWIW, you'd need to add the using statement to your view (@using Humanizer), but you can do that just once in _ViewImports.cshtml.

Also, depending on what you actually want the display name for, you can always just create a custom tag helper. For example, to automatically do this with labels, you can simply inherit from LabelTagHelper (or create your own) and use you own custom logic for determining the display name to show there, instead of worrying about changing the behavior of something like DisplayNameFor. You can also create a custom tag helper to just output the titleized name as above:

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());
    }
}

Then:

<titleize asp-for="ProposalNotes" />

That's a bit of overkill for something so simple, admittedly, but you could beef it up by stealing the logic from LabelTagHelper to support custom display names, as well, if the attribute is actually applied.