【问题标题】:Extract Display name and description Attribute from within a HTML helper从 HTML 帮助器中提取显示名称和描述属性
【发布时间】:2011-02-11 20:42:12
【问题描述】:

我正在构建一个自定义的 HTML.LabelFor 助手,如下所示:

public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> self, Expression<Func<TModel, TValue>> expression, Boolean showToolTip)
{
  var metadata = ModelMetadata.FromLambdaExpression(expression, self.ViewData);
  ...
}

为了能够获得属性的正确名称,我使用以下代码:

metadata.DisplayName

关于我得到的 ModelView 类的属性:

[DisplayName("Titel")]

问题是我还需要一个描述。有一个名为 Display 的属性,它具有名称和描述,但我看不到如何使用上述代码中的元数据变量来提取它?

【问题讨论】:

    标签: c# reflection asp.net-mvc-2 attributes html-helper


    【解决方案1】:

    免责声明:以下内容仅适用于 ASP.NET MVC 3(如果您使用的是以前的版本,请参阅底部的更新)

    假设以下模型:

    public class MyViewModel
    {
        [Display(Description = "some description", Name = "some name")]
        public string SomeProperty { get; set; }
    }
    

    还有以下观点:

    <%= Html.LabelFor(x => x.SomeProperty, true) %>
    

    在您的自定义助手中,您可以从元数据中获取此信息:

    public static MvcHtmlString LabelFor<TModel, TValue>(
        this HtmlHelper<TModel> self, 
        Expression<Func<TModel, TValue>> expression, 
        bool showToolTip
    )
    {
        var metadata = ModelMetadata.FromLambdaExpression(expression, self.ViewData);
        var description = metadata.Description; // will equal "some description"
        var name = metadata.DisplayName; // will equal "some name"
        // TODO: do something with the name and the description
        ...
    }
    

    备注:[DisplayName("foo")][Display(Name = "bar")] 在同一个模型属性上是多余的,[Display] 属性中使用的名称优先于 metadata.DisplayName


    更新:

    我之前的回答不适用于 ASP.NET MVC 2.0。在 .NET 3.5 中,默认情况下无法使用 DataAnnotations 填充几个属性,Description 就是其中之一。要在 ASP.NET MVC 2.0 中实现这一点,您可以使用自定义模型元数据提供程序:

    public class DisplayMetaDataProvider : DataAnnotationsModelMetadataProvider
    {
        protected override ModelMetadata CreateMetadata(
            IEnumerable<Attribute> attributes, 
            Type containerType,
            Func<object> modelAccessor, 
            Type modelType, 
            string propertyName
        )
        {
            var metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
    
            var displayAttribute = attributes.OfType<DisplayAttribute>().FirstOrDefault();
            if (displayAttribute != null)
            {
                metadata.Description = displayAttribute.Description;
                metadata.DisplayName = displayAttribute.Name;
            }
            return metadata;
        }
    }
    

    您将在Application_Start注册:

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        RegisterRoutes(RouteTable.Routes);
        ModelMetadataProviders.Current = new DisplayMetaDataProvider();
    }
    

    然后助手应该按预期工作:

    public static MvcHtmlString LabelFor<TModel, TValue>(
        this HtmlHelper<TModel> self, 
        Expression<Func<TModel, TValue>> expression, 
        bool showToolTip
    )
    {
        var metadata = ModelMetadata.FromLambdaExpression(expression, self.ViewData);
        var description = metadata.Description; // will equal "some description"
        var name = metadata.DisplayName; // will equal "some name"
        // TODO: do something with the name and the description
        ...
    }
    

    【讨论】:

    • 谢谢!但这不起作用,DisplayName 和 Description 为空?请注意,这是在 MVC2 而不是 MVC3 中。如果我做对了,你的解决方案只能在 MVC3 中工作?
    • @SnowJim,是的,有几个属性在 .NET 3.5 中默认无法用 DataAnnotations 填充,而 Description 就是其中之一。在 .NET 4.0 中它应该可以工作。
    • @SnowJim,请参阅我的更新以了解 ASP.NET MVC 2 中的解决方法。
    • 这是我遇到的最全面的答案之一,所以 +1。谢谢@DarinDimitrov!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-28
    • 1970-01-01
    • 2011-10-09
    • 2015-08-24
    • 1970-01-01
    相关资源
    最近更新 更多