Web API 2 XML序列化和DataContracts

时间:2016-12-09 18:33:41

标签: c# xml serialization asp.net-web-api2 datacontractserializer

当我的Web API 2解决方案在请求XML时尝试解析结果时,我遇到了错误。

通过更多的研究来了解。使用默认XML序列化程序解析时,词典存在问题。

基类中的属性在看起来像这样解析时很好:

public Dictionary<string, CustomObject> MyThings{ get; set; }

这没有所有DataContract和DataSerialization属性。

但是,如果我做同样的事情,但将值类型定义为'对象',我得到错误:

  

如果您正在使用DataContractSerializer或将任何静态未知类型添加到已知类型列表中,请考虑使用DataContractResolver - 例如,使用KnownTypeAttribute属性或将它们添加到传递给序列化程序的已知类型列表中。 / p>

根据我的理解,我需要用期望的类型来装饰类,这很好,理论上,序列化器应该将对象序列化为XML。

当我装饰类时会得到同样的错误。

我不知道这是否因为能够解析'对象'类型仍有局限性。但是,从我在其他人的问题和例子中看到的情况来看,如果说属性属于类型,那就有用了;

object 

而不是

IDictionary<string, object>

我只是想知道我是否误解了如何使用DataContract,KnownType和/或DataMember属性,或者这实际上是否仍然是使用默认XML Serializer解析字典的限制。

我在这里已经介绍了一些例子和问题,但是我找不到一个好的解决方案。

过去有没有人想出这个?如果是这样,你是如何解决这个限制的?

我尝试过使用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>();
        }
    }

1 个答案:

答案 0 :(得分:1)

您需要将return n, n - vType_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>(); } } 声明为已知类型,但在对象图中不会遇到该类型。相反,您需要声明将显示为字典的实际类型,因为这些类型无法静态推断。

完成此操作后,数据协定序列化程序将生成类似于以下内容的XML:

Dictionary<string, Type_X>

鉴于具体的课程:

<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; } } 属性是w3c standard attribute,允许元素断言其类型。数据协定序列化程序使用它来指示要序列化的多态类型的实际合同名称。有关更多信息,请参阅Data Contract Known Types