In the example code below, I get this error:
Element TestSerializeDictionary123.Customer.CustomProperties vom Typ System.Collec
Try Serializating through BinaryFormatter
private void Deserialize()
{
try
{
var f_fileStream = File.OpenRead(@"dictionarySerialized.xml");
var f_binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
myDictionary = (Dictionary<string, myClass>)f_binaryFormatter.Deserialize(f_fileStream);
f_fileStream.Close();
}
catch (Exception ex)
{
;
}
}
private void Serialize()
{
try
{
var f_fileStream = new FileStream(@"dictionarySerialized.xml", FileMode.Create, FileAccess.Write);
var f_binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
f_binaryFormatter.Serialize(f_fileStream, myDictionary);
f_fileStream.Close();
}
catch (Exception ex)
{
;
}
}
What about to mark Customer class as DataContract and its properties as DataMembers. DataContract serializer will do the serialization for you.
I've just found this blog post by Rakesh Rajan which describes one possible solution:
Override XmlSerialization by making the type implement the System.Xml.Serialization.IXmlSerializable class. Define how you want the object to be serialized in XML in the WriteXml method, and define how you could recreate the object from an xml string in the ReadXml method.
But this wouldn't work as your Dictionary contains an object
rather than a specific type.
You can't (short of doing it all yourself, which is horrible); the xml serializer isn't going to have a clue what to do with object
, as it doesn't include type metadata in the wire format. One (hacky) option would be to stream these all as strings for the purposes of serialization, but then you have a lot of extra parsing (etc) code to write.
Here's a generic dictionary class that knows how to serialize itself:
public class XmlDictionary<T, V> : Dictionary<T, V>, IXmlSerializable {
[XmlType("Entry")]
public struct Entry {
public Entry(T key, V value) : this() { Key = key; Value = value; }
[XmlElement("Key")]
public T Key { get; set; }
[XmlElement("Value")]
public V Value { get; set; }
}
System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema() {
return null;
}
void IXmlSerializable.ReadXml(System.Xml.XmlReader reader) {
this.Clear();
var serializer = new XmlSerializer(typeof(List<Entry>));
reader.Read(); // Why is this necessary?
var list = (List<Entry>)serializer.Deserialize(reader);
foreach (var entry in list) this.Add(entry.Key, entry.Value);
reader.ReadEndElement();
}
void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer) {
var list = new List<Entry>(this.Count);
foreach (var entry in this) list.Add(new Entry(entry.Key, entry.Value));
XmlSerializer serializer = new XmlSerializer(list.GetType());
serializer.Serialize(writer, list);
}
}
You can use Binary serialization instead. (Just make sure all your classes are marked as [Serializable]
. Of course, it won't be in XML format, but you didn't list that as a requirement :)