Web API 2 XML 序列化和 DataContracts
Web API 2 XML Serialization and DataContracts
我的 Web API 2 解决方案在请求 XML 时尝试解析结果时出现错误。
通过更多的研究来找出答案。使用默认 XML 序列化程序解析字典时会出现问题。
基础 class 中的 属性 解析正常,如下所示:
public Dictionary<string, CustomObject> MyThings{ get; set; }
这在没有所有 DataContract 和 DataSerialization 属性的情况下也有效。
但是,如果我做同样的事情,但将值类型定义为 'object',我会得到错误:
Consider using a DataContractResolver if you are using DataContractSerializer or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to the serializer.
根据我的理解,这很好,我需要用预期的类型装饰 class 并且序列化程序理论上应该将对象序列化为 XML.
当我装饰 class 得到同样的错误。
我不知道这是不是因为能够解析 'object' 类型仍然存在限制。但是从我在其他人的问题和示例中看到的情况来看,如果说 属性 是类型;
object
而不是
IDictionary<string, object>
我只是想知道我是否误解了如何使用 DataContract、KnownType and/or DataMember 属性,或者这是否实际上仍然是使用默认 XML 序列化程序解析字典的限制。
我已经在此处查看了很多示例和问题,但还没有找到一个好的解决方案。
过去有没有人想到过这个?如果是这样,您是如何解决这个限制的?
我尝试过使用 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>
声明为已知类型,但是对象图中未遇到该类型。相反,您需要声明将显示为字典 values 的实际类型,因为无法静态推断这些类型。
这样做之后,数据协定序列化程序将生成 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 standard attribute that allows an element to assert its type. The data contract serializer uses it to indicate the actual contract name of the polymorphic type being serialized. For more, see Data Contract Known Types。
我的 Web API 2 解决方案在请求 XML 时尝试解析结果时出现错误。
通过更多的研究来找出答案。使用默认 XML 序列化程序解析字典时会出现问题。
基础 class 中的 属性 解析正常,如下所示:
public Dictionary<string, CustomObject> MyThings{ get; set; }
这在没有所有 DataContract 和 DataSerialization 属性的情况下也有效。
但是,如果我做同样的事情,但将值类型定义为 'object',我会得到错误:
Consider using a DataContractResolver if you are using DataContractSerializer or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to the serializer.
根据我的理解,这很好,我需要用预期的类型装饰 class 并且序列化程序理论上应该将对象序列化为 XML.
当我装饰 class 得到同样的错误。
我不知道这是不是因为能够解析 'object' 类型仍然存在限制。但是从我在其他人的问题和示例中看到的情况来看,如果说 属性 是类型;
object
而不是
IDictionary<string, object>
我只是想知道我是否误解了如何使用 DataContract、KnownType and/or DataMember 属性,或者这是否实际上仍然是使用默认 XML 序列化程序解析字典的限制。
我已经在此处查看了很多示例和问题,但还没有找到一个好的解决方案。
过去有没有人想到过这个?如果是这样,您是如何解决这个限制的?
我尝试过使用 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>
声明为已知类型,但是对象图中未遇到该类型。相反,您需要声明将显示为字典 values 的实际类型,因为无法静态推断这些类型。
这样做之后,数据协定序列化程序将生成 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 standard attribute that allows an element to assert its type. The data contract serializer uses it to indicate the actual contract name of the polymorphic type being serialized. For more, see Data Contract Known Types。