繁体   English   中英

如何设置ModelMetadata的Description属性

[英]How-to set the Description property of the ModelMetadata

我已经在属性上放置了Description属性,但是无论如何,ModelMetada上的Description属性都为null。

[Description("sss")]
public int Id { get; set; }

顺便说一句, I've putted放了corect吗?

编辑

我看过MVC的源代码。 它似乎不是一个错误。 decsription属性从未使用过。 Metadata类中有一个属性,但从未设置或调用此属性。 CreateMetadata方法没有使用decription属性的代码。解决方案是覆盖create方法并编辑模板。

这是一个古老的帖子,但是也遇到了与cfeduke略有不同的解决方案。 想通了,如果有人在这里发生,我会发贴。

至少在MVC 3中,您不需要定义自定义元数据类型,而只需定义提供程序。 通过阅读MVC源代码,元数据并不是从所有可能的属性中构建的,仅是以下几个方面:

DisplayAttribute提供:

  • 描述
  • ShortDisplayName
  • 水印
  • 订购

完全不检查DescriptionAttribute,因此,如果在模型上定义,则元数据将反映为空。 如果您在设置元数据属性时遇到问题,请检查提供程序是否实际读取了该内容。

class MyDataAnnotationsModelMetadataProvider : 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);

        // Description - The default provider reads the description from DisplayAttribute.
        // Here we check for a description attribute as well.  This will overwrite anything
        // set before as we assume a Description attribute is more specific.
        DescriptionAttribute descriptionAttribute = attributes.OfType<DescriptionAttribute>().FirstOrDefault();
        if (descriptionAttribute != null)
        {
            metaData.Description = descriptionAttribute.Description;
        }

        return metaData;
    }
}

在尝试找到如何使之工作时,我遇到了一篇博客文章,该文章指出Description和Watermark都不适用于DataAnnotations框架的当前版本。

我想出了一个大概如下的解决方法:

(免责声明:此代码是从我的编译版本中编辑的,以将其从通过合成构建的元数据提供程序中删除,因此如果没有一些润色,可能无法直接编译。)

public class CustomDataAnnotationsModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
    protected override ModelMetadata CreateMetadata(IEnumerable<System.Attribute> attributes, System.Type containerType, System.Func<object> modelAccessor, System.Type modelType, string propertyName)
    {
        var baseModelMetadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
        var result = new CustomMetadata(modelMetadataProvider, containerType, modelAccessor, modelType, propertyName, attributes.OfType<DisplayColumnAttribute>().FirstOrDefault(), attributes)
        {
            TemplateHint = !string.IsNullOrEmpty(templateName) ?                              templateName : baseModelMetaData.TemplateHint,
            HideSurroundingHtml = baseModelMetaData.HideSurroundingHtml,
            DataTypeName = baseModelMetaData.DataTypeName,
            IsReadOnly = baseModelMetaData.IsReadOnly,
            NullDisplayText = baseModelMetaData.NullDisplayText,
            DisplayFormatString = baseModelMetaData.DisplayFormatString,
            ConvertEmptyStringToNull = baseModelMetaData.ConvertEmptyStringToNull,
            EditFormatString = baseModelMetaData.EditFormatString,
            ShowForDisplay = baseModelMetaData.ShowForDisplay,
            ShowForEdit = baseModelMetaData.ShowForEdit,
            DisplayName = baseModelMetaData.DisplayName
        };
        return result;
    }
}

public class CustomMetadata : DataAnnotationsModelMetadata
{
    private string _description;

    public CustomMetadata(DataAnnotationsModelMetadataProvider provider, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName, DisplayColumnAttribute displayColumnAttribute, IEnumerable<Attribute> attributes)
            : base(provider, containerType, modelAccessor, modelType, propertyName, displayColumnAttribute)
        {
            var descAttr = attributes.OfType<DescriptionAttribute>().SingleOrDefault();
                    _description = descAttr != null ? descAttr.Description : "";
        }

        // here's the really important part
        public override string Description
        {
            get
            {
                return _description;
            }
            set
            {
                _description = value;
            }
        }
}

然后在Application_Start或您注册模型元数据提供程序的任何位置的Global.asax中:

ModelMetadataProviders.Current = new CustomMetadataProvider();

正确的属性是DisplayNameAttribute。 您可以创建自己的属性,但是它必须派生自DisplayNameAttribute。

如果您使用的是MVC 3,则可以使用[AdditionalMetadata("AttributeName", "AttributeValue")]作为自定义属性。

然后,您可以在扩展方法中执行以下操作:

if (ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).AdditionalValues.ContainsKey("AttributeName")) {    
 return ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).AdditionalValues["AttributeName"].ToString()    
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM