代码之家  ›  专栏  ›  技术社区  ›  user137348

如何设置modelmetadata的description属性

  •  1
  • user137348  · 技术社区  · 16 年前

    我在属性上输入了一个description属性,但modelmetada上的description属性仍然为空。

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

    BTW是 I've putted 科里特?

    编辑

    我看过MVC源代码。好像不是虫子。decsription属性从未使用过。元数据类中有一个属性,但从未设置或调用此属性。CreateMetadata方法没有可用于描述属性的代码。解决方案是重写Create方法并编辑模板。

    4 回复  |  直到 14 年前
        1
  •  1
  •   cfeduke    16 年前

    在试图找到如何实现这一点的时候,我看到了一篇博客文章,上面说描述和水印都不能用在当前的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;
                }
            }
    }
    

    然后在global.asax的application中启动或注册模型元数据提供程序:

    ModelMetadataProviders.Current = new CustomMetadataProvider();
    
        2
  •  2
  •   Leniency    15 年前

    这是一个旧的帖子,但遇到这个问题时,也有一个与cfeduke稍有不同的解决方案。我想我会把它贴出来,以防其他人在这里发生。

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

    DisplayAttribute提供:

    • 描述
    • 短显示名称
    • 水印
    • 秩序

    根本不检查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;
        }
    }
    
        3
  •  0
  •   Davi Fiamenghi    16 年前

    正确的属性是displaynameattribute。您可以执行自己的属性,但它必须从displaynameattribute派生。

        4
  •  0
  •   Bob    14 年前

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

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

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