Serializing a list of Key/Value pairs to XML

Slauma picture Slauma · Apr 17, 2010 · Viewed 35.5k times · Source

I have a list of key/value pairs I'd like to store in and retrieve from a XML file. So this task is similar as described here. I am trying to follow the advice in the marked answer (using a KeyValuePair and a XmlSerializer) but I don't get it working.

What I have so far is a "Settings" class ...

public class Settings
{
    public int simpleValue;
    public List<KeyValuePair<string, int>> list;
}

... an instance of this class ...

Settings aSettings = new Settings();

aSettings.simpleValue = 2;

aSettings.list = new List<KeyValuePair<string, int>>();
aSettings.list.Add(new KeyValuePair<string, int>("m1", 1));
aSettings.list.Add(new KeyValuePair<string, int>("m2", 2));

... and the following code to write that instance to a XML file:

XmlSerializer serializer = new XmlSerializer(typeof(Settings));
TextWriter writer = new StreamWriter("c:\\testfile.xml");
serializer.Serialize(writer, aSettings);
writer.Close();

The resulting file is:

<?xml version="1.0" encoding="utf-8"?>
<Settings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <simpleValue>2</simpleValue>
  <list>
    <KeyValuePairOfStringInt32 />
    <KeyValuePairOfStringInt32 />
  </list>
</Settings>

So neither key nor value of the pairs in my list are stored though the number of elements is correct. Obviously I am doing something basically wrong. My questions are:

  • How can I store the key/value pairs of the list in the file?
  • How can I change the default generated name "KeyValuePairOfStringInt32" of the elements in the list to some other name like "listElement" I'd like to have?

Answer

Petar Minchev picture Petar Minchev · Apr 17, 2010

KeyValuePair is not serializable, because it has read-only properties. Here is more information(thanks to Thomas Levesque). For changing the generated name use the [XmlType] attribute.

Define your own like this:

[Serializable]
[XmlType(TypeName="WhateverNameYouLike")]
public struct KeyValuePair<K, V>
{
  public K Key 
  { get; set; }

  public V Value 
  { get; set; }
}