[英]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提供:
完全不检查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.