Can't get DisplayAttribute Name
I have a partial class generated from EF4 that I assign a MetadataType
in order to display on an ASP.NET MVC3 form the name for a control and it works as expected.
I would like to use the same DisplayAttribute
assigned to each property to retreive the displayed Name
value for the property for another purpose. My classes are like this:
using Domain.Metadata;
namespace Domain
{
[MetadataType(typeof(ClassAMetada))]
public partial class ClassA
{}
}
namespace Domain.Metadata
{
public class ClassAMetada
{
[Display(Name = "Property 1 Description", Order = 1)]
public Boolean Property1;
[Display(Name = "Property 2 Description", Order = 2)]
public Boolean Property2;
}
}
I've already saw this 3 posts and tried the presented solutions:
- How to get Di开发者_如何学GosplayAttribute of a property by Reflection?
- C# Buddy Classes / Meta Data and Reflection
- Get [DisplayName] attribute of a property in strongly-typed way
but none of them can retreive the attribute Name
value; the attribute is not found and, therefore, is null
, so it returns an empty string (3rd question) or the property name (1st question); the 2nd question was slighty changed in order to discover the attribute, but the result is also an empty string.
Can you please help me with this one? Thanks a lot!
EDIT:
here is the code for the 2 methods I'm using to retreive the attribute value (both work separately). Both are quite similar: the first one uses a string with the name of the property and the other one uses a lamba expression.
private static string GetDisplayName(Type dataType, string fieldName)
{
DisplayAttribute attr;
attr = (DisplayAttribute)dataType.GetProperty(fieldName).GetCustomAttributes(typeof(DisplayAttribute), true).SingleOrDefault();
if (attr == null)
{
MetadataTypeAttribute metadataType = (MetadataTypeAttribute)dataType.GetCustomAttributes(typeof(MetadataTypeAttribute), true).FirstOrDefault();
if (metadataType != null)
{
var property = metadataType.MetadataClassType.GetProperty(fieldName);
if (property != null)
{
attr = (DisplayAttribute)property.GetCustomAttributes(typeof(DisplayAttribute), true).SingleOrDefault();
}
}
}
return (attr != null) ? attr.Name : String.Empty;
}
private static string GetPropertyName<T>(Expression<Func<T>> expression)
{
MemberExpression propertyExpression = (MemberExpression)expression.Body;
MemberInfo propertyMember = propertyExpression.Member;
Object[] displayAttributes = propertyMember.GetCustomAttributes(typeof(DisplayAttribute), true);
if (displayAttributes != null && displayAttributes.Length == 1)
return ((DisplayAttribute)displayAttributes[0]).Name;
return propertyMember.Name;
}
Did you consider putting your display name into resources? It's much easier to reuse than all this reflection magic.
You can simply do:
[Display(Name = "Property1Name", ResourceType = typeof(Resources), Order = 1)]
public Boolean Property1;
And add Resources.resx
file to your project with Property1Name
key and "Property 1 Description" value. Of course you'll probably have to set default resources access from internal
to public
.
Later, in other places you need those strings simply call:
string displayName = Domain.Resources.Property1Name;
精彩评论