Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / April 2008

Tip: Looking for answers? Try searching our database.

serialize dictionary<string, string> collection in .net3.5

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Andy B - 07 Apr 2008 03:37 GMT
Is it possible to serialize to xml a dictionary<string, string> object in
.net 3.5?
Family Tree Mike - 07 Apr 2008 03:54 GMT
No, this has not changed in 3.5.

> Is it possible to serialize to xml a dictionary<string, string> object in
> ..net 3.5?
Andy B - 07 Apr 2008 04:45 GMT
Got any simular ideas that can be used for that type of thing. More or less
a key/value string pair that can be serialized?

> No, this has not changed in 3.5.
>
>> Is it possible to serialize to xml a dictionary<string, string> object in
>> ..net 3.5?
Marc Gravell - 07 Apr 2008 05:21 GMT
Not sure if this is a great idea, but it works:

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.ComponentModel;
using System.Collections.Specialized;

class Program
{
   static void Main()
   {
       Foo foo = new Foo
       {
           Values =
           {
               { "abc", "def" },
               { "ghi", "jkl" }
           }
       };
       XmlSerializer ser = new XmlSerializer(typeof(Foo));
       StringWriter writer = new StringWriter();
       ser.Serialize(writer, foo);
       string xml = writer.ToString();

       StringReader reader = new StringReader(xml);
       Foo newFoo = (Foo) ser.Deserialize(reader);
       foreach (KeyValuePair<string, string> pair in newFoo.Values)
       {
           Console.WriteLine(pair.Key + ": " + pair.Value);
       }
   }
}

[Serializable]
public class Foo
{
   private readonly Dictionary<string, string> values
       = new Dictionary<string,string>();
   [XmlIgnore]
   public Dictionary<string, string> Values { get { return
values; } }

   [EditorBrowsable(EditorBrowsableState.Never)]
   [XmlArray(ElementName="Values")]
   [XmlArrayItem(ElementName="Add", Type=typeof(StringPair))]
   public StringPairList ValuesProxy
   {
       get { return new StringPairList(values); }
   }
}

[Serializable]
public class StringPairList : IList<StringPair>
{
   private readonly IDictionary<string,string> parent;
   public StringPairList(IDictionary<string, string> parent)
   {
       if (parent == null) throw new ArgumentNullException("parent");
       this.parent = parent;
   }

   #region IList<StringPair> Members

   public int IndexOf(StringPair item)
   {
       throw new NotImplementedException();
   }

   public void Insert(int index, StringPair item)
   {
       throw new NotImplementedException();
   }

   public void RemoveAt(int index)
   {
       throw new NotImplementedException();
   }

   public StringPair this[int index]
   {
       get { throw new NotImplementedException(); }
       set { throw new NotImplementedException(); }
   }

   #endregion

   #region ICollection<StringPair> Members

   public void Add(StringPair item)
   {
       parent.Add(item.Key, item.Value);
   }

   public void Clear()
   {
       parent.Clear();
   }

   public bool Contains(StringPair item)
   {
       throw new NotImplementedException();
   }

   public void CopyTo(StringPair[] array, int arrayIndex)
   {
       throw new NotImplementedException();
   }

   public int Count
   {
       get { return parent.Count; }
   }

   public bool IsReadOnly
   {
       get { return false; }
   }

   public bool Remove(StringPair item)
   {
       throw new NotImplementedException();
   }

   #endregion

   #region IEnumerable<StringPair> Members

   public IEnumerator<StringPair> GetEnumerator()
   {
       foreach (var pair in parent)
       {
           yield return new StringPair
           {
               Key = pair.Key,
               Value = pair.Value
           };
       }
   }

   #endregion

   #region IEnumerable Members

   System.Collections.IEnumerator
System.Collections.IEnumerable.GetEnumerator()
   {
       return GetEnumerator();
   }

   #endregion
}

[Serializable]
public class StringPair
{
   [XmlAttribute]
   public string Key { get; set; }
   [XmlAttribute]
   public string Value { get; set; }
}
Marc Gravell - 07 Apr 2008 07:46 GMT
Actually, it looks like it only needs IEnumerable<StringPair>
and Add(StringPair) - I incorrectly assumed it would use the
Add method from IList<StringPair> (in fact it finds the Add
separately); removing all the dross
makes the solution far less grungy - satisfactory, even.

Example (K&R for brevity):

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Xml.Serialization;

static class Program {
   static void Main() {
       Foo foo = new Foo {
           Values = {
               { "abc", "def" },
               { "ghi", "jkl" }
           }
       };
       XmlSerializer ser = new XmlSerializer(typeof(Foo));
       StringWriter writer = new StringWriter();
       ser.Serialize(writer, foo);
       string xml = writer.ToString();

       StringReader reader = new StringReader(xml);
       Foo newFoo = (Foo) ser.Deserialize(reader);
       foreach (KeyValuePair<string, string> pair in newFoo.Values) {
           Console.WriteLine(pair.Key + ": " + pair.Value);
       }
   }
}

[Serializable]
public class Foo {
   private readonly Dictionary<string, string> values
       = new Dictionary<string,string>();
   [XmlIgnore]
   public Dictionary<string, string> Values { get { return
values; } }

   [EditorBrowsable(EditorBrowsableState.Never)]
   [XmlArray(ElementName="Values")]
   [XmlArrayItem(ElementName="add", Type=typeof(StringPair))]
   public StringPairList ValuesProxy {
       get { return new StringPairList(values); }
   }
}
[Serializable]
public sealed class StringPairList : IEnumerable<StringPair> {
   private readonly IDictionary<string,string> parent;
   public StringPairList(IDictionary<string, string> parent) {
       if (parent == null) throw new ArgumentNullException("parent");
       this.parent = parent;
   }
   public void Add(StringPair item) {
       parent.Add(item.Key, item.Value);
   }
   public IEnumerator<StringPair> GetEnumerator() {
       foreach (var pair in parent) {
           yield return new StringPair {
               Key = pair.Key, Value = pair.Value
           };
       }
   }
   IEnumerator IEnumerable.GetEnumerator() {
       return GetEnumerator();
   }
}

[Serializable]
public sealed class StringPair {
   [XmlAttribute("key")]
   public string Key { get; set; }
   [XmlAttribute("value")]
   public string Value { get; set; }
}
Family Tree Mike - 07 Apr 2008 12:44 GMT
There is the SerializableDictionary class that I pointed someone to last
week.  I don't recall if you were in that discussion.  If not, the link is
http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx.

> Got any simular ideas that can be used for that type of thing. More or less
> a key/value string pair that can be serialized?
[quoted text clipped - 3 lines]
> >> Is it possible to serialize to xml a dictionary<string, string> object in
> >> ..net 3.5?
Marc Gravell - 07 Apr 2008 12:57 GMT
> There is the SerializableDictionary class that I pointed someone to last
> week.  I don't recall if you were in that discussion.  If not, the link is
> http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx.

I must have skipped that one ;-p
It looks like another viable solution; one caveat with
SerializableDictionary is that the schema isn't very well defined (in
terms of a WSDL or similar - I believe it uses "any") - but it will
work. And less effort than adding attributes and a facade property...

Marc

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.