我如何从类级别的PropertyInfo获得DataContract属性

本文关键字:PropertyInfo 获得 DataContract 属性 | 更新日期: 2023-09-27 18:11:57

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

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检查仍然测试为真,但仍然无法强制转换。我通过观察变量查看了objCustomAttributes属性(当它进入方法时),它显示了类型DataContractAttribute的1个属性,然而,当我到达asPropInfo.GetType()时,它已更改为Serializable

这可能是我已经在这个太久了,我没有想清楚,但有人有任何输入吗?

更新:我能够删除GetType(),只是直接调用GetCustomAttributes(),然而,结果仍然不是我需要的。下面是发生的事情:

假设一个Person类包含一个Person类型的成员,如下所示:

[DataContract(Name = "Employee")]
public class PersonDto{
    public string FirstName {get;set;}
    public string LastName {get;set;}
    [DataMember(Name = "Boss")]
    public Person Supervisor {get;set;}
}

刮擦过程中发生的事情是Supervisor正在作为PropertyInfo与它的DataMember属性一起传递,而我的扩展正在阅读它并返回"Boss",这完全有意义。然而,我在这个阶段实际需要的是DataContract属性,原因如下:

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

我如何从类级别的PropertyInfo获得DataContract属性

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

var attrName = asPropInfo.GetCustomAttributes(typeof(Attribute), true).SingleOrDefault();