什么是DisplayAttribute.GroupName属性用于?

时间:2011-07-11 11:36:08

标签: asp.net-mvc-3 data-annotations

我正试图找出DisplayAttribute.GroupName属性的有效用法。

MSDN说:

  

用于对UI中的字段进行分组的值。

但我不会称之为全面的解释。这让我觉得GroupName可以用来创建某些字段周围的组框。但话说:

  

不要使用此属性来获取GroupName属性的值。   请改用 GetDescription 方法。空值或空字符串   有效的。

似乎与此相矛盾。

那么这个属性是什么?我应该使用它(可能使用自定义模板或自定义ModelMetadataProvider)以便在我的字段周围渲染分组框?

3 个答案:

答案 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类,那么这也将按预期工作。