using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; using System.Xml; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.IO; using System.Security.Permissions; namespace lib { [Serializable] public class SerializableDictionary: Dictionary, IXmlSerializable, ISerializable { #region Constants private const string DictionaryNodeName = "Dictionary"; private const string ItemNodeName = "Item"; private const string KeyNodeName = "Key"; private const string ValueNodeName = "Value"; #endregion #region Constructors public SerializableDictionary() { } public SerializableDictionary( IDictionary dictionary ) : base( dictionary ) { } public SerializableDictionary( IEqualityComparer comparer ) : base( comparer ) { } public SerializableDictionary( int capacity ) : base( capacity ) { } public SerializableDictionary( IDictionary dictionary, IEqualityComparer comparer ) : base( dictionary, comparer ) { } public SerializableDictionary( int capacity, IEqualityComparer comparer ) : base( capacity, comparer ) { } #endregion #region ISerializable Members protected SerializableDictionary( SerializationInfo info, StreamingContext context ) { int itemCount = info.GetInt32("ItemCount"); for( int i = 0; i < itemCount; i++ ) { KeyValuePair kvp = (KeyValuePair)info.GetValue(String.Format( $"Item{i}" ), typeof(KeyValuePair)); this.Add( kvp.Key, kvp.Value ); } } //[SecurityPermission( SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter )] void ISerializable.GetObjectData( SerializationInfo info, StreamingContext context ) { info.AddValue( "ItemCount", this.Count ); int itemIdx = 0; foreach( KeyValuePair kvp in this ) { info.AddValue( String.Format( $"Item{itemIdx}" ), kvp, typeof( KeyValuePair ) ); itemIdx++; } } #endregion #region IXmlSerializable Members void IXmlSerializable.WriteXml( System.Xml.XmlWriter writer ) { //writer.WriteStartElement(DictionaryNodeName); foreach( KeyValuePair kvp in this ) { writer.WriteStartElement( ItemNodeName ); writer.WriteStartElement( KeyNodeName ); KeySerializer.Serialize( writer, kvp.Key ); writer.WriteEndElement(); writer.WriteStartElement( ValueNodeName ); ValueSerializer.Serialize( writer, kvp.Value ); writer.WriteEndElement(); writer.WriteEndElement(); } //writer.WriteEndElement(); } void IXmlSerializable.ReadXml( System.Xml.XmlReader reader ) { if( reader.IsEmptyElement ) { return; } // Move past container if( !reader.Read() ) { throw new XmlException( "Error in Deserialization of Dictionary" ); } //reader.ReadStartElement(DictionaryNodeName); while( reader.NodeType != XmlNodeType.EndElement ) { reader.ReadStartElement( ItemNodeName ); reader.ReadStartElement( KeyNodeName ); TKey key = (TKey)KeySerializer.Deserialize(reader); reader.ReadEndElement(); reader.ReadStartElement( ValueNodeName ); TVal value = (TVal)ValueSerializer.Deserialize(reader); reader.ReadEndElement(); reader.ReadEndElement(); this.Add( key, value ); reader.MoveToContent(); } //reader.ReadEndElement(); reader.ReadEndElement(); // Read End Element to close Read of containing node } System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema() { return null; } #endregion #region Private Properties protected XmlSerializer ValueSerializer { get { if( valueSerializer == null ) { valueSerializer = new XmlSerializer( typeof( TVal ) ); } return valueSerializer; } } private XmlSerializer KeySerializer { get { if( keySerializer == null ) { keySerializer = new XmlSerializer( typeof( TKey ) ); } return keySerializer; } } #endregion #region Private Members private XmlSerializer keySerializer = null; private XmlSerializer valueSerializer = null; #endregion } }