当我的Web API 2解决方案尝试解析XML时,我一直在遇到错误。
通过更多的研究来找出答案。用默认的XML序列化器解析时,字典存在问题。
基类中的属性在看起来像这样的情况下可以很好地解析:
public Dictionary<string, CustomObject> MyThings{ get; set; }
这在没有所有数据合同和数据序列化属性的情况下起作用。
但是,如果我做同样的事情,但是将值类型定义为"对象",我会得到错误:
如果使用datacontractserializer或将任何类型添加到已知类型列表中,请考虑使用DataContractresolver,如果使用newtytypeattribute属性或将它们添加到传递到序列化器的已知类型列表中。/p>
据我所知,这是很好的,我需要用预期类型来装饰类,从理论上讲,序列化器应将对象序列化为XML。
当我装饰班级时,会出现相同的错误。
我不知道这是否是因为能够解析"对象"类型仍然存在限制。但是,从我在其他民族问题和示例中看到的内容,如果说该属性是类型的;
object
而不是
IDictionary<string, object>
我只是想知道我是否正在误解如何使用数据合同,newtype和/或datamember属性,或者实际上仍然是用默认的XML serialializer解析字典的限制。
我在这里介绍了许多示例和问题,但是在一个很好的解决方案上都缺乏。
过去有人想出这个吗?如果是这样,您是如何解决限制的?
我尝试使用keyValuepairs列表,但也失败了。
谢谢!
示例:
[DataContract]
[KnownType(typeof(Dictionary<string, Type_X>))]
[KnownType(typeof(Dictionary<string, Type_Y>))]
public abstract class BaseClass
{
[DataMember]
public Dictionary<string, object> BaseDictionary{ get; set; }
public BaseClass()
{
BaseDictionary = new Dictionary<string, object>();
}
}
您需要将Type_X
和Type_Y
声明为已知类型:
[DataContract]
[KnownType(typeof(Type_X))]
[KnownType(typeof(Type_Y))]
public abstract class BaseClass
{
[DataMember]
public Dictionary<string, object> BaseDictionary { get; set; }
public BaseClass()
{
BaseDictionary = new Dictionary<string, object>();
}
}
您所做的是将Dictionary<string, Type_X>
声明为已知类型,但是该类型在对象图中没有遇到。相反,您需要声明将显示为字典 value 的实际类型,因为这些类型无法静态地推断。
这样做了,数据合同序列化器将生成XML,看起来像:
<ConcreteClass xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Question41066771">
<BaseDictionary xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d2p1:KeyValueOfstringanyType>
<d2p1:Key>X</d2p1:Key>
<d2p1:Value i:type="Type_X">
<X>x</X>
</d2p1:Value>
</d2p1:KeyValueOfstringanyType>
<d2p1:KeyValueOfstringanyType>
<d2p1:Key>Y</d2p1:Key>
<d2p1:Value i:type="Type_Y">
<Y>y</Y>
</d2p1:Value>
</d2p1:KeyValueOfstringanyType>
</BaseDictionary>
</ConcreteClass>
给定具体类:
[DataContract]
public class ConcreteClass : BaseClass
{
}
[DataContract]
public class Type_X
{
[DataMember]
public string X { get; set; }
}
[DataContract]
public class Type_Y
{
[DataMember]
public string Y { get; set; }
}
i:type
属性是W3C标准属性,允许元素断言其类型。数据合同序列化器使用它来指示序列化多态性类型的实际合同名称。有关更多信息,请参见数据合同已知类型。