1

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

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

顺便说一句,I've putted正确吗?

编辑

我已经查看了 MVC 源代码。这似乎不是一个错误。描述属性只是从未使用过。Metadata 类中有一个属性,但从未设置或调用此属性。CreateMetadata 方法没有代码可用于 decriction 属性。解决方案是覆盖 create 方法并编辑模板。

4

4 回答 4

2

这是一篇旧帖子,但也遇到了这个问题,解决方案与 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;
    }
}
于 2011-06-14T20:14:26.750 回答
1

在尝试找到如何使这项工作正常工作时,我遇到了一篇博客文章,其中说 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();
于 2010-07-08T19:11:09.713 回答
0

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

于 2010-06-02T01:19:31.503 回答
0

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

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

if (ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).AdditionalValues.ContainsKey("AttributeName")) {    
 return ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).AdditionalValues["AttributeName"].ToString()    
}
于 2011-10-12T19:46:17.290 回答