简体   繁体   English

如何设置ModelMetadata的Description属性

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

I've putted a Description attribute on my property,but the Description property on the ModelMetada is null anyway. 我已经在属性上放置了Description属性,但是无论如何,ModelMetada上的Description属性都为null。

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

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

EDIT 编辑

I've had a look at the MVC source. 我看过MVC的源代码。 It doesn't seem to be a bug. 它似乎不是一个错误。 The decsription attribute is just never used. decsription属性从未使用过。 There is a property in the Metadata class but this property is never set or called. Metadata类中有一个属性,但从未设置或调用此属性。 The CreateMetadata method has no code to work with the decription attribute.The solution would be to override the create method and also edit the templates. CreateMetadata方法没有使用decription属性的代码。解决方案是覆盖create方法并编辑模板。

This is an old post, but ran into this as well have have a slightly different solution than cfeduke. 这是一个古老的帖子,但是也遇到了与cfeduke略有不同的解决方案。 Figured I'd post it in case anyone else happens by here. 想通了,如果有人在这里发生,我会发贴。

At least in MVC 3, you don't need to define a custom metadata type, just the provider. 至少在MVC 3中,您不需要定义自定义元数据类型,而只需定义提供程序。 Reading through the MVC source code, metadata isn't build from all possible attributes, just a few: 通过阅读MVC源代码,元数据并不是从所有可能的属性中构建的,仅是以下几个方面:

DisplayAttribute provides: DisplayAttribute提供:

  • Description 描述
  • ShortDisplayName ShortDisplayName
  • Watermark 水印
  • Order 订购

The DescriptionAttribute isn't checked for at all so if defined on your model, the metadata will reflect null. 完全不检查DescriptionAttribute,因此,如果在模型上定义,则元数据将反映为空。 If you're having problems with metadata attributes not being set, check that the provider actually reads that. 如果您在设置元数据属性时遇到问题,请检查提供程序是否实际读取了该内容。

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

While trying to find how to get this working I came across a blog post that said neither Description nor Watermark are usable with the present incarnation of the DataAnnotations framework. 在尝试找到如何使之工作时,我遇到了一篇博客文章,该文章指出Description和Watermark都不适用于DataAnnotations框架的当前版本。

I came up with a workaround that looks roughly like this: 我想出了一个大概如下的解决方法:

(Disclaimer: this code is edited from my compiling version to remove it from a metadata provider built through composition so it may not compile directly without some touchups.) (免责声明:此代码是从我的编译版本中编辑的,以将其从通过合成构建的元数据提供程序中删除,因此如果没有一些润色,可能无法直接编译。)

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

Then in your Global.asax in Application_Start or wherever you register your model metadata providers: 然后在Application_Start或您注册模型元数据提供程序的任何位置的Global.asax中:

ModelMetadataProviders.Current = new CustomMetadataProvider();

The correct attribute is DisplayNameAttribute. 正确的属性是DisplayNameAttribute。 You can do your own attribute, but it must derive from DisplayNameAttribute. 您可以创建自己的属性,但是它必须派生自DisplayNameAttribute。

If you're using MVC 3 you can use [AdditionalMetadata("AttributeName", "AttributeValue")] for custom attributes. 如果您使用的是MVC 3,则可以使用[AdditionalMetadata("AttributeName", "AttributeValue")]作为自定义属性。

In your extension methods you can then do something like: 然后,您可以在扩展方法中执行以下操作:

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