Reputation: 791
I've hit a snag when working on serialization of Dictionary collections using the standard .NET DataContractSerializer class. It seems to serialize the dictionary correctly:
<GameObjectData xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<Id>
<GameObjectData>ddd95b29-0e98-4f1c-8c0a-ef2815a90f78</GameObjectData>
<d2p1:Value xmlns:d4p1="https://id.unity.com/en/organizations/lucas-cardoso-2534099">
<X>-4.10677576</X>
<Y>0.05</Y>
<Z>1.01642287</Z>
</d2p1:Value>
</Id>
<Id>
<GameObjectData>7a7b90d6-975d-4166-93a0-f45b4fd0bf51</GameObjectData>
<d2p1:Value xmlns:d4p1="https://id.unity.com/en/organizations/lucas-cardoso-2534099">
<X>0.84188956</X>
<Y>0.05</Y>
<Z>0.09239852</Z>
</d2p1:Value>
</Id>
</GameObjectData>
But when trying to read the object from file, it complains as if it didn't expect it to be an array of key-value pairs:
SerializationException: Deserializing type 'NodeGameObjectDict'. Expecting state 'EndElement'. Encountered state 'Element' with name 'Id' with namespace 'https://id.unity.com/en/organizations/lucas-cardoso-2534099'
The most damning thing is it actually works if the Dictionary has only one Key-Value pair, so it's definitely hitting a snag thinking it's not actually an array. What gives?
This is the code I'm using:
[DataContract(Name = "NodeGraphContainer", Namespace = "https://id.unity.com/en/organizations/lucas-cardoso-2534099")]
public class NodeGraphContainer {
...
[DataMember(Name = "GameObjectData")]
public NodeGameObjectDict nodeGameObjectData;
...
}
...
[CollectionDataContract(ItemName = "Id", KeyName = "GameObjectData", Namespace = "https://id.unity.com/en/organizations/lucas-cardoso-2534099")]
public class NodeGameObjectDict : Dictionary<Guid, NodeGameObjectData> { }
And my serialization/deserialization code:
public void Serialize() {
DataContractSerializer serializer = new DataContractSerializer(typeof(NodeGraphContainer));
XmlWriterSettings settings = new XmlWriterSettings() { Indent = true };
XmlWriter writer = XmlWriter.Create(new FileStream("Assets/Data/maptest.xml", FileMode.Create), settings);
serializer.WriteObject(writer, this);
writer.Close();
}
public static NodeGraphContainer Deserialize() {
DataContractSerializer serializer = new DataContractSerializer(typeof(NodeGraphContainer));
try {
XmlReader reader = XmlDictionaryReader.Create(new FileStream("Assets/Data/maptest.xml", FileMode.Open));
NodeGraphContainer container = (NodeGraphContainer)serializer.ReadObject(reader);
reader.Close();
return container;
} catch (FileNotFoundException ex) {
Debug.Log("No map file found");
return null;
}
}
Upvotes: 1
Views: 214
Reputation: 791
The actual answer is that Unity does not implement .NET correctly, so Dictionary classes aren't being deserialized correctly. A short test case proved that suspicion. Already reported the bug!
Upvotes: 0