1

當我的Web API 2解決方案在請求XML時嘗試解析結果時,我一直在收到錯誤。Web API 2 XML序列化和數據合同

來找出通過一些更多的研究。字典在使用默認XML序列化程序進行分析時遇到問題。

在基類的屬性解析正常,當它看起來像這樣:

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

這工作沒有所有的DataContract和DataSerialization屬性。

但是,如果我做同樣的事情,但定義的值類型爲「對象」我得到的錯誤:

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.

這是罰款,從我的理解我需要裝飾預計類型的類理論上,串行器應該將對象序列化爲XML。

當我裝飾類獲得相同的錯誤。

我不知道這是否是因爲能夠解析'對象'類型仍然有限制。但從我在其他民族問題和例子中看到的情況來看,如果說財產是類型的,

object 

代替

IDictionary<string, object> 

我只是想知道如果我誤解如何使用DataContract,KnownType和/或數據成員屬性或這實際上仍與解析字典的限制默認的XML序列化器。

我在這裏經歷了一些例子和問題,但我很快就提出了一個很好的解決方案。

有沒有人想出了過去?如果是這樣,你是如何解決這個限制的?

我嘗試過使用KeyValuePair的列表,但我也失敗了。

謝謝!

例子:

[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

需要聲明Type_XType_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>爲已知的類型,但該類型不在對象圖中遇到。相反,您需要聲明將顯示爲字典的實際類型,因爲無法靜態推斷這些類型。

這樣做之後,數據契約序列化器將生成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,允許一個元素斷言它的類型。數據協定序列化程序使用它來指示要序列化的多態類型的實際協定名稱。欲瞭解更多信息,請參閱Data Contract Known Types

+0

啊......是的,我看到它在做什麼。我沒有點擊這是爲了繼承鏈,以便序列化器知道要嘗試和序列化的類型。我的解決方案非常類似,感謝您指引我朝着正確的方向發展! – Schanckopotamus