2012-10-12 130 views
5

是不知道在組件A:使用的DataContractSerializer反序列化派生類型時派生類型預先

[DataContract]  
     public class Base 
     { 
      [DataMember] 
      public string SomeText { get; set; } 
     } 

在大會B:

internal class Helper 
     { 
      internal static Base Deserialize(string serializedInstanceOfTypeBase) 
    { 
        DataContractSerializer serializer = new DataContractSerializer(typeof (Base)); 
        XmlReader reader = XmlReader.Create(new StringReader(serializedInstanceOfTypeBase)); 
        return (Base)serializer.ReadObject(reader); 
    } 
    } 

在大會C:

[DataContract]  
     public class Derived : Base 
     { 
      [DataMember] 
      public string SomeMoreText { get; set; } 
     } 

如果我序列Derived類型的一個實例,並把它傳遞給Helper.Deserialize()方法,它失敗與SerializationException

錯誤在第1個位置2從名稱空間 期待元件「基地」的「http://模式.datacontract.org/2004/07'..遇到'元素' ,名稱爲'Derived',命名空間爲 'http://schemas.datacontract.org/2004/07'。

我該如何擺脫這個問題?

我知道KnownType屬性,但在編譯程序集A和B時,我完全不知道它的派生類型。所以我不能使用該解決方案。

我的產品設計比較複雜,我不能在這裏完全發佈。 Helper.Desrialize()方法只是得到一個string的論點。對於程序集A或B,目前還沒有辦法(至少)知道Base類的派生類型,即使在運行時也是如此。

組件B引用組件A,但一個& B不能引用裝配C.

我使用C#4.0。如果您提供的解決方案不使用DataContractSerializer,那也沒關係。

+1

我不知道一個開箱即用的解決方案。根據我的經驗,當我有各種各樣的類型時,我實際上會用類型信息對我的內容進行雙重序列化。也就是說,我將擁有一個'SerializedObject',它將包含完整的類型信息(程序集名稱,完整的類名稱)及其序列化的XML字符串。我的數據傳輸層會強烈地將自己對照SerializedObject類型,獲取對該類型的運行時引用(例如通過Type.GetType),然後通過XmlSerializer反序列化XML數據。 –

+0

你的意思是'Base'類在'Assembly A'中,'Derived'類在'Assembly C'中?如果是這樣,那麼我認爲這是問題所在。數據合同應該在同一個程序集中定義。 DataContracts不應該在程序集之間拆分。 – jags

回答

2

您是否在運行時知道的類型?如果是這樣,一個簡單的方法可能只是:

List<Type> knownTypes = ...; // now that you know what to expect 
DataContractSerializer serializer = new DataContractSerializer(
    typeof(Base), knownTypes); 
+0

感謝您的回答。這非常有幫助,但我已經爲該問題添加了更多細節。我應該在之前添加這些細節。請注意'Helper'類是不同的程序集,它不是'public'。此外,'Deserialize'方法只是獲取任何字符串值。 – Learner