如何在mvc视图中访问Dataannotation的“GroupName”?

时间:2011-05-24 20:25:02

标签: asp.net-mvc

我想在MVC视图中访问DataAnnotation的{​​{1}}。 例如,假设我的一个模型属性就像

GroupName

现在,我如何访问视图中的[Display(Order = 1, GroupName= "Passport Detail", Name = "Passport #")] [Required()] [StringLength(20)] public string PassportNo { get; set; } ? 我希望在 MVC 中实现类似this的内容。

4 个答案:

答案 0 :(得分:2)

我也在研究这个问题,看起来你必须为一个属性做很多代码,而这个属性应该就在那里......对吧?

我不是必须扩展当前逻辑,而是使用AdditionalValuesAttribute来定义我自己的“GroupName”。当然,你可以通过扩展它来获得所有“花式裤子”,但它基本上是这样的:

    if (ViewData.ModelMetadata.AdditionalValues.ContainsKey("GroupName")) {
        var groupName = ViewData.ModelMetadata.AdditionalValues["GroupName"].ToString();
    }

答案 1 :(得分:1)

我找到了解决方案。
我们可以通过使用DataAnnotationsModelMetadataProvider来实现这一目标 例如

public class MetadataProvider : 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);

        var disp = attributes.OfType<DisplayAttribute>().FirstOrDefault();
        if (disp != null)
        {
            if (disp.GroupName != null)
                metadata.AdditionalValues.Add("GroupName", disp.GroupName);
        }

        return metadata;
    }
}

在mvc视图中,我们可以像往常一样使用AdditionalValues

答案 2 :(得分:0)

好吧,我没看到MVC使用它。 DataAnnotations并不是MVC的一部分,因此不能使用所有道具。如果你想使用它,我会说你需要创建一个可以创建这些组的HTML帮助器。

好的,我想我看到了你想要的东西......你想让它为你自动模板化。只需使用EditorTemplates。 http://www.codecapers.com/post/Display-and-Editor-Templates-in-ASPNET-MVC-2.aspx

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