如何在类级别从PropertyInfo获取DataContract属性?

时间:2013-05-02 01:14:13

标签: c# .net reflection

我有一个扩展方法,我尝试从对象中提取一些元数据,例如:

public static string ToTypeName(this object obj)
{
    string name;
    var asType = obj.GetType();
    if (Attribute.IsDefined(asType, typeof(DataMemberAttribute)) || Attribute.IsDefined(asType, typeof(DataContractAttribute)))
    {
        var attrName = obj.GetType().GetCustomAttributes(typeof(DataContractAttribute), true).SingleOrDefault() as DataContractAttribute;
        name = string.IsNullOrEmpty(attrName.Name) ? asType.Name : attrName.Name;
    }
    else
    {
        name = asType.Name;
    }
    return name;
}

我目前正在使用它来废弃使用各种属性修饰的对象中的元数据。在此示例中,它正在查找DataContractAttribute,然后从Name属性中提取值。这很好用。

但是,有时候该对象属于PropertyInfo类型。发生的事情是Attribute.IsDefined正在测试为真,因此输入要被删除的块,但是,它无法转换,因此attrName将出现空值。

我在前一个块之前添加了这个块:

if (obj is PropertyInfo)
{
    var asPropInfo = obj as PropertyInfo;
    if (Attribute.IsDefined(asPropInfo, typeof(DataMemberAttribute)) || Attribute.IsDefined(asPropInfo, typeof(DataContractAttribute)))
    {
        var attrName = asPropInfo.GetType().GetCustomAttributes(typeof(Attribute), true).SingleOrDefault();
        if (attrName is DataMemberAttribute)
        {
            var attr = attrName as DataMemberAttribute;
            name = string.IsNullOrEmpty(attr.Name) ? asType.Name : attr.Name;
        }
        else if (attrName is DataContractAttribute)
        {
            var attr = attrName as DataContractAttribute;
            name = string.IsNullOrEmpty(attr.Name) ? asType.Name : attr.Name;
        }
    }
}

IsDefined检查仍然是真的,但仍然无法投射。我通过监视变量查看了CustomAttributes的{​​{1}}属性(当它进入方法时),它显示了obj类型的1个属性,但是,当我到达asPropInfo.GetType时(),它已更改为DataContractAttribute

可能是因为我已经这么久了,而且我没有想清楚,但有人有任何意见吗?

更新: 我能够删除Serializable并直接调用GetType(),但结果仍然不是我需要的。以下是似乎正在发生的事情:

想象一下,Person类包含Person类型的成员,如下所示:

GetCustomAttributes()

在刮擦过程中发生的事情是[DataContract(Name = "Employee")] public class PersonDto{ public string FirstName {get;set;} public string LastName {get;set;} [DataMember(Name = "Boss")] public Person Supervisor {get;set;} } 作为PropertyInfo传递了它的Supervisor属性,我的扩展正在阅读它并返回“Boss”,这完全有道理。但是,我在这个阶段实际需要的是DataMember属性,这就是原因:

DataContract属性被序列化时,它将序列化为“Boss”,我需要知道,所以我将其保存到DTO。但是,我还需要知道“Boss”是序列化的“类型”,即“员工”。这可能看起来很奇怪,但最终有意义lol。我正在使用它来帮助生成API的帮助文档。在内部,类类型可能是“PersonDto”,但显示给客户端的类型是“Employee”。因此,在帮助文档方面,开发人员知道有一个“Boss”元素,但他们也需要知道它只是“Employee”的一个实例(就他们而言),以便他们可以查找该对象的文档。这有道理吗?

1 个答案:

答案 0 :(得分:2)

我相信你不需要在asPropInfo上调用GetType。试试这个:

var attrName = asPropInfo.GetCustomAttributes(typeof(Attribute), true).SingleOrDefault();
相关问题