如何遍历所有模型显示(Name =)属性值

时间:2012-10-13 00:38:28

标签: c# asp.net-mvc reflection

我发现code of @RichTebb很棒,它返回Model属性DisplayName。

但是如何迭代所有Model Display(Name =)属性值呢?

感谢您的任何线索!

@RichTebb代码

public static class HelperReflectionExtensions
    {
        public static string GetPropertyDisplayString<T>(Expression<Func<T, object>> propertyExpression)
        {
            var memberInfo = GetPropertyInformation(propertyExpression.Body);
            if (memberInfo == null)
            {
                throw new ArgumentException(
                    "No property reference expression was found.",
                    "propertyExpression");
            }

            var displayAttribute = memberInfo.GetAttribute<DisplayAttribute>(false);

            if (displayAttribute != null)
            {
                return displayAttribute.Name;
            }
// ReSharper disable RedundantIfElseBlock
            else
// ReSharper restore RedundantIfElseBlock
            {
                var displayNameAttribute = memberInfo.GetAttribute<DisplayNameAttribute>(false);
                if (displayNameAttribute != null)
                {
                    return displayNameAttribute.DisplayName;
                }
// ReSharper disable RedundantIfElseBlock
                else
// ReSharper restore RedundantIfElseBlock
                {
                    return memberInfo.Name;
                }
            }
        }

        public static MemberInfo GetPropertyInformation(Expression propertyExpression)
        {
            Debug.Assert(propertyExpression != null, "propertyExpression != null");
            var memberExpr = propertyExpression as MemberExpression;
            if (memberExpr == null)
            {
                var unaryExpr = propertyExpression as UnaryExpression;
                if (unaryExpr != null && unaryExpr.NodeType == ExpressionType.Convert)
                {
                    memberExpr = unaryExpr.Operand as MemberExpression;
                }
            }

            if (memberExpr != null && memberExpr.Member.MemberType == MemberTypes.Property)
            {
                return memberExpr.Member;
            }

            return null;
        }

        public static T GetAttribute<T>(this MemberInfo member, bool isRequired)
            where T : Attribute
        {
            var attribute = member.GetCustomAttributes(typeof(T), false).SingleOrDefault();

            if (attribute == null && isRequired)
            {
                throw new ArgumentException(
                    string.Format(
                        CultureInfo.InvariantCulture,
                        "The {0} attribute must be defined on member {1}",
                        typeof(T).Name,
                        member.Name));
            }

            return (T)attribute;
        }

    }

示例:

string displayName = ReflectionExtensions.GetPropertyDisplayName<SomeClass>(i => i.SomeProperty);

enter image description here

2 个答案:

答案 0 :(得分:8)

3个小时,我找到了解决方案。

首先

 [Display(Name = "Employed: ")]
  public Nullable<bool> Employed { get; set; }

 [DisplayName("Employed: ")]
  public Nullable<bool> Employed { get; set; }

不一样。 :)对于MVC,我们必须使用这种语法[DisplayName("Employed: ")]

类元数据属性也应该看起来像

[MetadataType(typeof(PatientMetadata))]
public partial class Patient
{
....
 internal sealed class PatientMetadata
        {

最后是CODE

 public static class DisplayNameHelper
    {
        public static string GetDisplayName(object obj, string propertyName)
        {
            if (obj == null) return null;
            return GetDisplayName(obj.GetType(), propertyName);

        }

        public static string GetDisplayName(Type type, string propertyName)
        {
            var property = type.GetProperty(propertyName);
            if (property == null) return null;

            return GetDisplayName(property);
        }

        public static string GetDisplayName(PropertyInfo property)
        {
            var attrName = GetAttributeDisplayName(property);
            if (!string.IsNullOrEmpty(attrName))
                return attrName;

            var metaName = GetMetaDisplayName(property);
            if (!string.IsNullOrEmpty(metaName))
                return metaName;

            return property.Name.ToString(CultureInfo.InvariantCulture);
        }

        private static string GetAttributeDisplayName(PropertyInfo property)
        {
            var atts = property.GetCustomAttributes(
                typeof(DisplayNameAttribute), true);
            if (atts.Length == 0)
                return null;
            var displayNameAttribute = atts[0] as DisplayNameAttribute;
            return displayNameAttribute != null ? displayNameAttribute.DisplayName : null;
        }

        private static string GetMetaDisplayName(PropertyInfo property)
        {
            if (property.DeclaringType != null)
            {
                var atts = property.DeclaringType.GetCustomAttributes(
                    typeof(MetadataTypeAttribute), true);
                if (atts.Length == 0)
                    return null;

                var metaAttr = atts[0] as MetadataTypeAttribute;
                if (metaAttr != null)
                {
                    var metaProperty =
                        metaAttr.MetadataClassType.GetProperty(property.Name);
                    return metaProperty == null ? null : GetAttributeDisplayName(metaProperty);
                }
            }
            return null;
        }
    }

使用方法:

var t = patient.GetType();

                foreach (var pi in t.GetProperties())
                {
                    var dn = DisplayNameHelper.GetDisplayName(pi);
                }

DONE !!!!

答案 1 :(得分:0)

 Type t = model.GetType();
 foreach (PropertyInfo pi in t.GetProperties())
 {
     var attr = pi.GetCustomAttribute(DisplayNameAttribute, true);
     if (attr != null) ...

 }