Expanding upon my earlier problem, I've decided to (de)serialize my config file class which worked great.
I now want to store an associative array of drive letters to map (key is the drive letter, value is the network path) and have tried using Dictionary
, HybridDictionary
, and Hashtable
for this but I always get the following error when calling ConfigFile.Load()
or ConfigFile.Save()
:
There was an error reflecting type 'App.ConfigFile'. [snip] System.NotSupportedException: Cannot serialize member App.Configfile.mappedDrives [snip]
From what I've read Dictionaries and HashTables can be serialized, so what am I doing wrong?
[XmlRoot(ElementName="Config")] public class ConfigFile { public String guiPath { get; set; } public string configPath { get; set; } public Dictionary<string, string> mappedDrives = new Dictionary<string, string>(); public Boolean Save(String filename) { using(var filestream = File.Open(filename, FileMode.OpenOrCreate,FileAccess.ReadWrite)) { try { var serializer = new XmlSerializer(typeof(ConfigFile)); serializer.Serialize(filestream, this); return true; } catch(Exception e) { MessageBox.Show(e.Message); return false; } } } public void addDrive(string drvLetter, string path) { this.mappedDrives.Add(drvLetter, path); } public static ConfigFile Load(string filename) { using (var filestream = File.Open(filename, FileMode.Open, FileAccess.Read)) { try { var serializer = new XmlSerializer(typeof(ConfigFile)); return (ConfigFile)serializer.Deserialize(filestream); } catch (Exception ex) { MessageBox.Show(ex.Message + ex.ToString()); return new ConfigFile(); } } } }
NET objects is made easy by using the various serializer classes that it provides. But serialization of a Dictionary object is not that easy. For this, you have to create a special Dictionary class which is able to serialize itself. The serialization technique might be different in different business cases.
A serializable dictionary class for Unity. Unity cannot serialize standard dictionaries. This means that they won't show or be edited in the inspector and they won't be instantiated at startup. A classic workaround is to store the keys and values in separate arrays and construct the dictionary at startup.
There is a solution at Paul Welter's Weblog - XML Serializable Generic Dictionary
For some reason, the generic Dictionary in .net 2.0 is not XML serializable. The following code snippet is a xml serializable generic dictionary. The dictionary is serialzable by implementing the IXmlSerializable interface.
using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; [XmlRoot("dictionary")] public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable { public SerializableDictionary() { } public SerializableDictionary(IDictionary<TKey, TValue> dictionary) : base(dictionary) { } public SerializableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer) : base(dictionary, comparer) { } public SerializableDictionary(IEqualityComparer<TKey> comparer) : base(comparer) { } public SerializableDictionary(int capacity) : base(capacity) { } public SerializableDictionary(int capacity, IEqualityComparer<TKey> comparer) : base(capacity, comparer) { } #region IXmlSerializable Members public System.Xml.Schema.XmlSchema GetSchema() { return null; } public void ReadXml(System.Xml.XmlReader reader) { XmlSerializer keySerializer = new XmlSerializer(typeof(TKey)); XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue)); bool wasEmpty = reader.IsEmptyElement; reader.Read(); if (wasEmpty) return; while (reader.NodeType != System.Xml.XmlNodeType.EndElement) { reader.ReadStartElement("item"); reader.ReadStartElement("key"); TKey key = (TKey)keySerializer.Deserialize(reader); reader.ReadEndElement(); reader.ReadStartElement("value"); TValue value = (TValue)valueSerializer.Deserialize(reader); reader.ReadEndElement(); this.Add(key, value); reader.ReadEndElement(); reader.MoveToContent(); } reader.ReadEndElement(); } public void WriteXml(System.Xml.XmlWriter writer) { XmlSerializer keySerializer = new XmlSerializer(typeof(TKey)); XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue)); foreach (TKey key in this.Keys) { writer.WriteStartElement("item"); writer.WriteStartElement("key"); keySerializer.Serialize(writer, key); writer.WriteEndElement(); writer.WriteStartElement("value"); TValue value = this[key]; valueSerializer.Serialize(writer, value); writer.WriteEndElement(); writer.WriteEndElement(); } } #endregion }
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