我正试图找出DisplayAttribute.GroupName属性的有效用法。
MSDN说:
用于对UI中的字段进行分组的值。
但我不会称之为全面的解释。这让我觉得GroupName可以用来创建某些字段周围的组框。但话说:
不要使用此属性来获取GroupName属性的值。 请改用 GetDescription 方法。空值或空字符串 有效的。
似乎与此相矛盾。
那么这个属性是什么?我应该使用它(可能使用自定义模板或自定义ModelMetadataProvider)以便在我的字段周围渲染分组框?
答案 0 :(得分:1)
在MVC RTM源代码中没有使用的迹象。
“GetDescription”备注可能是文档中的复制/粘贴错误(每个字符串属性似乎都有一个返回可本地化值的GetXXX对应物),因此在这种情况下它应该是“GetGroupName”。
更新: 我会完全使用它:从UI视点组合在一起的字段。由于这只是模型上的数据注释,它仅声明这些字段在UI上“某种程度上”属于一个逻辑组,但具体的表示细节取决于基于元数据显示模型的“UI引擎”。 我认为在UI上“渲染”这个最有意义的方法就是你所说的:将分组的字段包装成一个部分或字段集。
当然可能会有MVC或其他自定义扩展的未来扩展,可以“自动”在UI上进行某种分组(无需编写检查元数据并生成部分的自定义代码),具体取决于此属性。但我很确定这样的扩展会做一些与你目前非常相似的事情。
答案 1 :(得分:0)
我最后编写了这个类,以便更容易访问GroupName:
public class ExtendedDataAnnotationsModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
public const string Key_GroupName = "GroupName";
protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
{
ModelMetadata modelMetadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
DisplayAttribute displayAttribute = attributes.OfType<DisplayAttribute>().FirstOrDefault();
if (displayAttribute != null)
modelMetadata.AdditionalValues[ExtendedDataAnnotationsModelMetadataProvider.Key_GroupName] = displayAttribute.GroupName;
return modelMetadata;
}
}
这个扩展方法:
public static string GetGroupName(this ModelMetadata modelMetadata)
{
if (modelMetadata.AdditionalValues.ContainsKey(ExtendedDataAnnotationsModelMetadataProvider.Key_GroupName))
return (modelMetadata.AdditionalValues[ExtendedDataAnnotationsModelMetadataProvider.Key_GroupName] as string);
return null;
}
来源:http://bradwilson.typepad.com/blog/2010/01/why-you-dont-need-modelmetadataattributes.html
答案 2 :(得分:0)
怎么样!!!必须工作:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
namespace System.Web.Mvc
{
public static class DisplayGroup
{
public static MvcHtmlString DisplayGroupName(this HtmlHelper helper, string groupName)
{
return MvcHtmlString.Create(groupName);
}
public static MvcHtmlString DisplayGroupNameFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
{
var type = typeof(TModel);
PropertyInfo propertyInfo = null;
var member = (MemberExpression)expression.Body;
var property = (PropertyInfo)member.Member;
var name = property.Name;
var metadataTypeInfo = type.GetCustomAttribute<MetadataTypeAttribute>();
if (metadataTypeInfo != null)
{
var metadataType = metadataTypeInfo.MetadataClassType;
propertyInfo = metadataType.GetProperties().Where(x => x.Name == name).FirstOrDefault();
if (propertyInfo == null)
{
propertyInfo = type.GetProperties().Where(x => x.Name == name).FirstOrDefault();
}
}
else
{
propertyInfo = type.GetProperties().Where(x => x.Name == name).FirstOrDefault();
}
string output = "";
var dattr = propertyInfo.GetCustomAttribute<DisplayAttribute>();
if (dattr != null)
{
if (dattr.GroupName == null)
{
output = propertyInfo.Name;
}
else
{
output = dattr.GroupName;
}
}
else
{
output = propertyInfo.Name;
}
return MvcHtmlString.Create(output);
}
}
}
public class MyModel
{
[Display(Name = "Number",GroupName="Invoice")]
string InvNo { get; set; }
}
然后简单地写:
@Html.DisplayGroupNameFor(x => x.InvNo)
注意:
NameSpace应该是:System.Web.Mvc
更新
很酷的是,如果您为dataAnnotation定义了MetaDataType
类,那么这也将按预期工作。