public static string GetDisplayName <TModel, TProperty>(this TModel model, Expression <Func <TModel, TProperty> > expression) { Type type = typeof(TModel); MemberExpression memberExpression = (MemberExpression)expression.Body; string propertyName = ((memberExpression.Member is PropertyInfo) ? memberExpression.Member.Name : null); // First look into attributes on a type and it's parents DisplayAttribute attr; attr = (DisplayAttribute)type.GetProperty(propertyName).GetCustomAttributes(typeof(DisplayAttribute), true).SingleOrDefault(); // Look for [MetadataType] attribute in type hierarchy // http://stackoverflow.com/questions/1910532/attribute-isdefined-doesnt-see-attributes-applied-with-metadatatype-class if (attr == null) { ModelMetadataTypeAttribute metadataType = (ModelMetadataTypeAttribute)type.GetCustomAttributes(typeof(ModelMetadataTypeAttribute), true).FirstOrDefault(); if (metadataType != null) { var property = metadataType.MetadataType.GetProperty(propertyName); if (property != null) { attr = (DisplayAttribute)property.GetCustomAttributes(typeof(DisplayNameAttribute), true).SingleOrDefault(); } } } return((attr != null) ? attr.Name : String.Empty); }
private static MemberInfo GetMatchingElement(MemberInfo element) { Type sourceType = element as Type; bool elementIsType = sourceType != null; if (sourceType == null) { sourceType = element.DeclaringType; } ModelMetadataTypeAttribute metadataTypeAttribute = (ModelMetadataTypeAttribute) Attribute.GetCustomAttribute(sourceType, typeof(ModelMetadataTypeAttribute), false); if (metadataTypeAttribute == null) { return(element); } sourceType = metadataTypeAttribute.MetadataType; if (elementIsType) { return(sourceType); } MemberInfo[] matchingMembers = sourceType.GetMember( element.Name, element.MemberType, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (matchingMembers.Length > 0) { MethodBase methodBase = element as MethodBase; if (methodBase == null) { return(matchingMembers[0]); } Type[] parameterTypes = methodBase.GetParameters().Select(pi => pi.ParameterType).ToArray(); return(matchingMembers.Cast <MethodBase>().FirstOrDefault(mb => MatchMethodBase(mb, parameterTypes)) ?? element); } return(element); }