I'm trying to use DataContractSerializer outside of WCF to serialize an object. The object in this case inherits from an old generic wrapper around CollectionBase e.g.
[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;
}
When this is serialized, I'm getting the following structure:
<FooCollection xmlns="http://schemas.datacontract.org/ ...>
<anyType>
<Name>...</Name>
<Value>...</Value>
</anyType>
</ArrayOfAnyType>
On deserializing I get the error:
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.
Googling this error shows a number of people who changed up their inheritance hierarchy to get the serialization working, or simply list problems with the approach. I haven't been able to find any examples of using XmlNode[] to deserialize this pattern of XML.
So my questions are:
I found the cause of the issue, not shown in my original question: MyCollectionBase implemented ISerializable.
The DataContractSerializer will use an ISerializable implementation before it uses any attributes. It also can't infer a contract from ISerializable, therefore there's no workaround for the anyType
deserialization.
This is why the KnownTypeAttribute wasn't working.