如何从界面的DisplayAttribute中检索数据?

时间:2016-07-26 13:02:01

标签: c# asp.net-mvc reflection

我有以下代码:

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

如何在服务器端使用代码实现相同的结果?为什么我不能用简单的反思来做呢?

3 个答案:

答案 0 :(得分:1)

您可以明确地查询注释的相关接口类型:

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

答案 1 :(得分:1)

你可以尝试这个

 var t = new TestClass();
 var a = t.GetType().GetInterface("TestInterface").GetProperty("Property").GetCustomAttributes(true);

答案 2 :(得分:0)

我为Description属性做了类似的事情。您可以重构此代码(或者更好,使其更通用),因此它也适用于Display属性,而不仅仅适用于枚举:

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"