Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serialize Class containing Dictionary member

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();             }         }     } } 
like image 322
dragonmantank Avatar asked Jan 30 '09 14:01

dragonmantank


People also ask

Can you serialize Dictionary C#?

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.

How do you serialize a dictionary in unity?

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.


1 Answers

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 } 
like image 162
osman pirci Avatar answered Oct 10 '22 05:10

osman pirci