Reputation: 4271
I have the following code:
public interface TestInterface
{
[Display(Name = "Test Property")]
int Property { get; }
}
class TestClass : TestAttribute
{
public int Property { get; set; }
}
Note, that the property of interface is marked with DisplayAttribute
.
When I am trying to get the value from attribute, the following code samples does not works.
First sample: direct access to property of class.
var t = new TestClass();
var a = t.GetType().GetProperty("Property").GetCustomAttributes(true);
Second sample: cast object to interface and get access to property.
var t = (TestInterface)new TestClass();
var a = t.GetType().GetProperty("Property").GetCustomAttributes(true);
But when I am passing object as a model for mvc view and calling @Html.DisplayNameFor(x => x.Property)
it returns the correct string "Test Property"
.
View
@model WebApplication1.Models.TestInterface
...
@Html.DisplayNameFor(x => x.Property)
renders as
Test Property
How can I achieve the same result with code on server side? And why I can not do it with simple reflection?
Upvotes: 0
Views: 811
Reputation: 703
You can try this one
var t = new TestClass();
var a = t.GetType().GetInterface("TestInterface").GetProperty("Property").GetCustomAttributes(true);
Upvotes: 1
Reputation: 1969
I have done something similar for the Description attribute. You could refactor this code (or better, make more generic) so it works for the Display attribute as well and not only for enums:
public enum LogCategories
{
[Description("Audit Description")]
Audit,
}
public static class DescriptionExtensions
{
public static string GetDescription<T, TType>(this T enumerationValue, TType attribute)
where T : struct
where TType : DescriptionAttribute
{
Type type = enumerationValue.GetType();
if (!type.IsEnum)
{
throw new ArgumentException("EnumerationValue must be of Enum type", "enumerationValue");
}
//Tries to find a DescriptionAttribute for a potential friendly name
//for the enum
MemberInfo[] memberInfo = type.GetMember(enumerationValue.ToString());
if (memberInfo != null && memberInfo.Length > 0)
{
object[] attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attribute is DescriptionAttribute)
{
if (attrs != null && attrs.Length > 0)
{
return ((DescriptionAttribute)attrs[0]).Description;
}
}
else
{
}
}
//If we have no description attribute, just return the ToString of the enum
return enumerationValue.ToString();
}
}
As you see, the code uses some reflection to detect any attributes marked on the member (in my case the DescriptionAttribute but it could be the DisplayAttribute too) and returns the Description property to the caller.
Usage:
string auditDescription = LogCategories.Audit.GetDescription(); // Output: "Audit Description"
Upvotes: 0
Reputation: 13458
You can explicitely query the associated interface types for annotations:
var interfaceAttributes = t.GetType()
.GetInterfaces()
.Select(x => x.GetProperty("Property"))
.Where(x => x != null) // avoid exception with multiple interfaces
.SelectMany(x => x.GetCustomAttributes(true))
.ToList();
The result list interfaceAttributes
will contain the DisplayAttribute
.
Upvotes: 1