2012-12-07 60 views
2

我想在WCF之外使用DataContractSerializer來序列化一個對象。在這種情況下,該對象繼承自CollectionBase周圍的舊通用包裝器,例如爲什麼我無法反序列化KnownType的anyType?

[KnownType(typeof(Foo)] 
[CollectionDataContract] 
class FooCollection : MyCollectionBase<Foo> 

[KnownType(typeof(FooCollection)] 
[KnownType(typeof(Foo)] 
[CollectionDataContract] 
class MyCollectionBase<T> : CollectionBase 

[DataContract] 
class Foo 
{ 
    [DataMember] 
    string Name; 
    [DataMember] 
    string Value; 
} 

當這種序列化,我得到以下結構:

<FooCollection xmlns="http://schemas.datacontract.org/ ...> 
    <anyType> 
    <Name>...</Name> 
    <Value>...</Value> 
    </anyType> 
</ArrayOfAnyType> 

在反序列化我的錯誤:

System.Runtime.Serialization.SerializationException : Element anyType from namespace http://schemas.datacontract.org/2004/07/MyAssembly cannot have child contents to be deserialized as an object. Please use XmlNode[] to deserialize this pattern of XML.

----> System.Xml.XmlException : End element 'anyType' from namespace 'http://schemas.datacontract.org/2004/07/MyAssembly' expected. Found element 'Name' from namespace 'http://schemas.datacontract.org/2004/07/MyAssembly'. Line 1, position xxx.

谷歌搜索這個錯誤顯示了一些人誰改變了他們的繼承層次以使序列化工作,或者簡單地列出問題的方法。我一直無法找到使用XmlNode []來反序列化這種XML模式的的任何示例。

所以我的問題是:

  1. 有沒有辦法說服DataContractSerializer的存儲在底層的ArrayList類型是Foo類型的?
  2. 如何實現XmlNode []解決方法?
  3. 唯一的解決方案是使用非非泛型支持的泛型集合嗎?

回答

2

我找到了問題的根源,而不是在我原來的questio所示n:MyCollectionBase實現了ISerializable。

DataContractSerializer將在使用任何屬性之前使用ISerializable實現。它也不能從ISerializable中推斷出合約,因此沒有解決方法。

這就是爲什麼KnownTypeAttribute不起作用。

2

鑑於你上面的代碼我用下面的代碼序列化和反序列化:

 var serializer = new DataContractSerializer(typeof(FooCollection)); 
     IList collection = new FooCollection(); 
     var foo = new Foo(); 
     foo.Name = "TestName"; 
     foo.Value = "Test value"; 
     collection.Add(foo); 
     StringBuilder sb = new StringBuilder(); 
     StringWriter writer = new StringWriter(sb); 
     XmlTextWriter xmlWriter = new XmlTextWriter(writer); 

     serializer.WriteObject(xmlWriter, collection); 
     Console.WriteLine(sb.ToString()); 
     var serialized = sb.ToString(); 

     var reader = new StringReader(serialized); 
     var xmlReader = new XmlTextReader(reader); 
     var deserialized = serializer.ReadObject(xmlReader); 

     return; 

不使用.NET 4.0和Visual Studio 2010中 如果你想改變元素的名稱出現任何問題所以它不是「anyType的」你可以改變的FooCollection類CollectionDataContract屬性爲:

[CollectionDataContract(ItemName="Foo")] 
+0

+1 - 這教會我不要測試自己的SSCCE! >< – Bringer128

相關問題