-2

I have in my model a ShortName attribute (expected to be "for the grid column label")

[MaxLength(256)]
[Display(Name = "Description", ShortName = "Desc.")]
public string Description { get; set; }

I use the DisplayFor in the Grid header of the column, as indicated by documentation.

<thead>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Description)
        </th>

However, I see the "Description" in my column header, not "Desc." as expected.

enter image description here

I tried to do the MS does for DisplayName:

public static class HtmlHelperDisplayNameExtensions
{
    public static string DisplayShortNameForModel(this IHtmlHelper htmlHelper)
    {
        if (htmlHelper == null)
        {
            throw new ArgumentNullException(nameof(htmlHelper));
        }

        return htmlHelper.DisplayShortNameForModel();
    }

    public static string DisplayShortNameFor<TModelItem, TResult>(
        this IHtmlHelper<IEnumerable<TModelItem>> htmlHelper,
        Expression<Func<TModelItem, TResult>> expression)
    {
        if (htmlHelper == null)
        {
            throw new ArgumentNullException(nameof(htmlHelper));
        }

        if (expression == null)
        {
            throw new ArgumentNullException(nameof(expression));
        }

        // << ???? >>>>>>>

        return htmlHelper.DisplayShortNameForInnerType(expression); // ??????

        // << ???? >>>>>>>
        // << ???? >>>>>>>
    }
}

The DisplayShortNameForInnerType unfortunalely does not exist

serge
  • 13,940
  • 35
  • 121
  • 205

1 Answers1

1

As far as I know, there is no build-in html extension method that could show the short name.

If you want to use it, you could only create the extension method by yourself. Besides, according to the source codes, you could also find the asp.net core team also return the HtmlString to render the view.

But if we want to use the extension method, we couldn't use DI to inject the ModelExpressionProvider which could get the display name attribute directly. We should write the logic by ourselves.

More details, you could refer to below codes:

public static class HtmlExtensions
{
    public static IHtmlContent DescriptionFor<TModel, TValue>(this IHtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
    {            
        var propertyName = ((PropertyInfo)((MemberExpression)expression.Body).Member).Name;
        var attribute = ((PropertyInfo)((MemberExpression)expression.Body).Member).CustomAttributes.Where(x=>x.AttributeType == typeof(DisplayAttribute));

        var shortname = attribute.FirstOrDefault().NamedArguments.Where(x => x.MemberName == "ShortName").FirstOrDefault().TypedValue;



        return new HtmlString(string.Format(@"<span>{0}</span>", shortname));
    }
}

Usage:

@Html.DescriptionFor(x => x.Description)

Result:

enter image description here

Brando Zhang
  • 22,586
  • 6
  • 37
  • 65
  • the problem in the OP code it not for the property itself, but for the IEnumerable, by eg. when you have to put a column header for the collections of objects): `IHtmlHelper> htmlHelper,` – serge Feb 16 '21 at 11:18
  • Your question is `How to use the ShortName attribute?` and there is no build-in `DisplayShortNameForInnerType `. As far as I know, this attribute isn't asp.net core build-in attribute, it could be used for all the C# application. The asp.net core doesn't have special method that could render this attribute to the html. So we could only write some custom extension method for it. If you have any issue about why this doesn't work, I suggest you could post this issue on the asp.net core github [issue](https://github.com/dotnet/aspnetcore/issues). – Brando Zhang Feb 17 '21 at 00:49