我有以下代码:
public interface TestInterface
{
[Display(Name = "Test Property")]
int Property { get; }
}
class TestClass : TestAttribute
{
public int Property { get; set; }
}
注意,接口的属性用DisplayAttribute
标记。当我试图从属性中获取值时,以下代码示例不起作用。
第一个示例:直接访问类的属性。
var t = new TestClass();
var a = t.GetType().GetProperty("Property").GetCustomAttributes(true);
第二个示例:将对象强制转换为接口并获取对属性的访问权限。
var t = (TestInterface)new TestClass();
var a = t.GetType().GetProperty("Property").GetCustomAttributes(true);
但当我传递对象作为mvc视图的模型并调用@Html.DisplayNameFor(x => x.Property)
时,它会返回正确的字符串"Test Property"
。
查看
@model WebApplication1.Models.TestInterface
...
@Html.DisplayNameFor(x => x.Property)
渲染为
Test Property
如何使用服务器端的代码实现相同的结果?为什么我不能通过简单的反思来做到这一点?
您可以显式地查询相关接口类型的注释:
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();
结果列表interfaceAttributes
将包含DisplayAttribute
。
你可以试试这个
var t = new TestClass();
var a = t.GetType().GetInterface("TestInterface").GetProperty("Property").GetCustomAttributes(true);
我已经为Description属性做了类似的操作。您可以重构此代码(或者更好地,使其更通用),使其也适用于Display属性,而不仅仅适用于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();
}
}
正如您所看到的,代码使用一些反射来检测成员上标记的任何属性(在我的情况下是DescriptionAttribute,但它也可能是DisplayAttribute),并将Description属性返回给调用方。
用法:
string auditDescription = LogCategories.Audit.GetDescription(); // Output: "Audit Description"