ASP.NET Core: ShortName in the Display attribute (DataAnnotations)

前端 未结 1 559
轮回少年
轮回少年 2021-01-23 10:04

In an ASP .NET Core 1.1 project (VS 2017) I try to use the ShortName attrubute of the Display property in order to use the DisplayFor

1条回答
  •  灰色年华
    2021-01-23 10:45

    To get the ShortName property using this method, you need to extract the Display attribute manually because it's not part of the default metadata. For example, something like this will work:

    var defaultMetadata = m as 
        Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultModelMetadata;
    if(defaultMetadata != null)
    {
        var displayAttribute = defaultMetadata.Attributes.Attributes
            .OfType()
            .FirstOrDefault();
        if(displayAttribute != null)
        {
            return displayAttribute.ShortName;
        }
    }
    return m.DisplayName;
    

    To plug that into your helpers, I would abstract away the method slightly as there's some duplicate code in there, so you would end up with a private method like this:

    private static IHtmlContent MetaDataFor(this IHtmlHelper html, 
        Expression> expression,
        Func property)
    {
        if (html == null) throw new ArgumentNullException(nameof(html));
        if (expression == null) throw new ArgumentNullException(nameof(expression));
    
        var modelExplorer = ExpressionMetadataProvider.FromLambdaExpression(expression, html.ViewData, html.MetadataProvider);
        if (modelExplorer == null) throw new InvalidOperationException($"Failed to get model explorer for {ExpressionHelper.GetExpressionText(expression)}");
        return new HtmlString(property(modelExplorer.Metadata));
    }
    

    And your two public methods like this:

    public static IHtmlContent DescriptionFor(this IHtmlHelper html, Expression> expression)
    {
        return html.MetaDataFor(expression, m => m.Description);
    }
    
    public static IHtmlContent ShortNameFor(this IHtmlHelper html, 
        Expression> expression)
    {
        return html.MetaDataFor(expression, m => 
        {
            var defaultMetadata = m as 
                Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultModelMetadata;
            if(defaultMetadata != null)
            {
                var displayAttribute = defaultMetadata.Attributes.Attributes
                    .OfType()
                    .FirstOrDefault();
                if(displayAttribute != null)
                {
                    return displayAttribute.ShortName;
                }
            }
            //Return a default value if the property doesn't have a DisplayAttribute
            return m.DisplayName;
        });
    }
    

    0 讨论(0)
提交回复
热议问题