I'm using DataContractSerializer
to serialize an object that contains a Dictionary<string,object>
member, which is marked with [DataMember()]
. The idea is to have a flexible bag of object attributes, and I don't know what those attributes could be.
This works great when I'm putting int
, double
and string
objects into the dictionary, but when I put a List<string>
in it fails to deserialize the object with:
System.InvalidOperationException: Node type Element is not supported in this operation.
The entire dictionary is serialized to XML, and it looks pretty reasonable:
<Attributes xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d2p1:KeyValueOfstringanyType>
<d2p1:Key>name</d2p1:Key>
<d2p1:Value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:string">Test object</d2p1:Value>
</d2p1:KeyValueOfstringanyType>
<d2p1:KeyValueOfstringanyType>
<d2p1:Key>x</d2p1:Key>
<d2p1:Value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:double">0.5</d2p1:Value>
</d2p1:KeyValueOfstringanyType>
<d2p1:KeyValueOfstringanyType>
<d2p1:Key>y</d2p1:Key>
<d2p1:Value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:double">1.25</d2p1:Value>
</d2p1:KeyValueOfstringanyType>
<d2p1:KeyValueOfstringanyType>
<d2p1:Key>age</d2p1:Key>
<d2p1:Value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:int">4</d2p1:Value>
</d2p1:KeyValueOfstringanyType>
<d2p1:KeyValueOfstringanyType>
<d2p1:Key>list-of-strings</d2p1:Key>
<d2p1:Value>
<d2p1:string>one string</d2p1:string>
<d2p1:string>two string</d2p1:string>
<d2p1:string>last string</d2p1:string>
</d2p1:Value>
</d2p1:KeyValueOfstringanyType>
</Attributes>
Note the list-of-strings
at the end there. It's got all the values but nothing indicating that it's a List<string>
or anything.
What's the correct way of handling this situation?
Try using the KnownTypeAttribute so that DataContractSerializer
knows about the List<string>
type. Unfortunately, that seems to go against your idea of not having to know about the types before hand.
I'm basing this on the following code, which uses DataContractSerializer
to serialize a Dictionary<string, object>
containing List<string>
:
Dictionary<string,object> dictionary = new Dictionary<string, object>();
dictionary.Add("k1", new List<string> { "L1", "L2", "L3" });
List<Type> knownTypes = new List<Type> { typeof(List<string>) };
DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary<string,object>), knownTypes);
MemoryStream stream = new MemoryStream();
serializer.WriteObject(stream, dictionary);
StreamReader reader = new StreamReader(stream);
stream.Position = 0;
string xml = reader.ReadToEnd();
If you knownTypes
is not provided to the DataContractSerializer
, it throws an exception.
SerializationException: Type 'System.Collections.Generic.List`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' with data contract name 'ArrayOfstring:http://schemas.microsoft.com/2003/10/Serialization/Arrays' is not expected. Consider using a DataContractResolver 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 DataContractSerializer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With