【问题标题】:How to iterate through the all Model Display(Name=) attribute values如何遍历所有 Model Display(Name=) 属性值
【发布时间】:2012-10-13 00:38:28
【问题描述】:

我发现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);

【问题讨论】:

    标签: c# asp.net-mvc reflection


    【解决方案1】:

    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);
                    }
    

    完成!!!!

    【讨论】:

      【解决方案2】:
       Type t = model.GetType();
       foreach (PropertyInfo pi in t.GetProperties())
       {
           var attr = pi.GetCustomAttribute(DisplayNameAttribute, true);
           if (attr != null) ...
      
       }
      

      【讨论】:

      • 谢谢!但是你能建议如何使用这一行吗? string displayName = ReflectionExtensions.GetPropertyDisplayName(i => i.SomeProperty);
      • 那又是什么问题?
      • 这个方法 ReflectionExtensions.GetPropertyDisplayName(i => i.SomeProperty);如果我们确切知道该文件名,则返回 DisplayName 属性值。我需要进行一些调整才能使用整个模型来获取模型中所有属性的 DisplayName 的所有值的列表。
      • 请再看一遍问题。
      • 你的意思是我们可以在这里看到的方法codeproject.com/Tips/389764/… 吗?
      猜你喜欢
      • 2015-07-23
      • 1970-01-01
      • 2010-10-06
      • 1970-01-01
      • 2010-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多