2012-02-20 62 views
0

我有一個應用程序1.0版帶班,如:XMLSerialization與多個命名空間 - backwardscompatibility

class MyBaseDTO 
{ 
    [XmlElementAttribute(DataType="base64Binary", IsNullable=true, ElementName="Data")] 
    public byte[] Data{get;set} 
} 

和子類

class MySubDTO 
{ 
    [XmlElementAttribute(DataType="base64Binary", IsNullable=true, ElementName="MoreData")] 
    public byte[] MoreData{get;set} 
} 

現在在1.1版本我想移動MySubDTO.MoreData到MyBaseDTO。 的問題是,當我用1.0服務器進行通信以1.1客戶端MOREDATA從未serialzed因爲XML的樣子:

<a:MyBaseDTO i:type="b:MySubDTO"><a:Data>...</a:Data><b:MoreData>...</b:MoreData></a:MyBaseDTO> 

如果我添加

class MyBaseDTO 
{ 
    [XmlElementAttribute(DataType="base64Binary", IsNullable=true, ElementName="Data")] 
    public byte[] Data(){get;set} 
    [XmlElementAttribute(DataType="base64Binary", IsNullable=true, ElementName="MoreData", NameSpace="MyBaseDTO")] 
    public byte[] MoreData(){get;set} 
} 

它的工作原理,當然,但我希望它能夠理解MoreData可能有兩個不同的名稱空間。我使用WCF在Web服務之間進行通信,並使用DataContractSerializer對服務器端的對象進行序列化。這可以完成嗎?

回答

0

您有幾種選擇:

  • 我認爲這是IExtensibleDataObject(擴展數據)被設計爲方案的那種!這個想法是,如果數據合同的v1版本使用擴展數據接口進行修飾,它將自動忽略,存儲和往返未來數據合同修訂版(包括未來未知類型)的數據,而不會出現任何問題。

要爲特定類型啓用往返,您的類型應爲IExtensibleDataObject接口。該接口包含一個屬性ExtensionData(返回ExtensionDataObject類型)。該屬性存儲來自當前版本未知的數據合約未來版本的任何數據。下面是我的意思的例子:

[DataContract] 
public class Person : IExtensibleDataObject 
{ 
    [DataMember] 
    public string fullName; 
    private ExtensionDataObject theData; 

    public virtual ExtensionDataObject ExtensionData 
    { 
     get { return theData; } 
     set { theData = value; } 
    } 
} 

當WCF基礎設施遇到數據不是原始數據的合同,IT賣場的一部分,在這個屬性來保存數據。除了臨時存儲以外,不以任何其他方式處理。如果該對象返回到起始位置,則還會返回原始(未知)數據。

您可以隨時通過在DataContractSerializer構造函數中將ignoreExtensionDataObject設置爲true或通過在ServiceBehaviorAttribute上將IgnoreExtensionDataObject屬性設置爲true來關閉此往返功能。它確實有一個性能問題,所以如果你不需要它,我會關閉它。

  • 上述指導確實要求您切換到DataContractSerializer。如果您無法爲此類型執行此操作,則可能必須使用IDataContractSurrogate將此XML類型轉換爲DataContract類型,該類型看起來與您所做的完全相同。還可以讓您在每種類型或每個對象的基礎上自定義JSON序列化和反序列化。