2

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

ここに画像の説明を入力してください

4

2 に答える 2

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
        {

そして最後にコード

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

終わり!!!!

于 2012-10-13T01:55:59.043 に答える
0
 Type t = model.GetType();
 foreach (PropertyInfo pi in t.GetProperties())
 {
     var attr = pi.GetCustomAttribute(DisplayNameAttribute, true);
     if (attr != null) ...

 }
于 2012-10-13T00:42:59.067 に答える