Why can't a dictionary be serialized? #72176
-
I copied a solution from the Internet, but it was useless. [XmlRoot("Languages")]
public class LanguageSettings<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
{
public XmlSchema GetSchema() => null;
public void ReadXml(XmlReader reader)
{
if (reader.IsEmptyElement)
return;
reader.Read();
while (reader.NodeType != XmlNodeType.EndElement)
{
object key = reader.GetAttribute("Title");
object value = reader.GetAttribute("Value");
Add((TKey)key, (TValue)value);
reader.Read();
}
}
public void WriteXml(XmlWriter writer)
{
foreach (var key in this)
{
writer.WriteStartElement("Language");
writer.WriteAttributeString("Title", key.Key.ToString());
writer.WriteAttributeString("Value", key.Value.ToString());
writer.WriteEndElement();
}
}
} Why is XmlSerializer serialization not allowed for dictionaries and even the entire dictionary interface? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
This has been the case for a long time as far as I can tell, check out some links below where people have been working around this issue since the early .NET days. As for serialization, it is possible, it is just not as straight forward as JSON serialization, there are quite a few ways to do this, here are a few: Option 1:using System.Xml.Linq; var dictionary = new Dictionary<string, int>
{
{ "text1", 111 },
{ "text2", 222 },
{ "text3", 333 }
};
XElement el = new XElement("Root",
dictionary.Select(kv => new XElement(kv.Key, kv.Value)));
Console.WriteLine(el); Result: <Root>
<text1>111</text1>
<text2>222</text2>
<text3>333</text3>
</Root> Option 2:using System.Xml.Linq;
var dictionary = new Dictionary<string, int>
{
{ "text1", 111 },
{ "text2", 222 },
{ "text3", 333 }
};
XElement el = new XElement("Root",
dictionary.Select(kv => new XElement("item",new XAttribute("id", kv.Key),new XAttribute("value", kv.Value))));
Console.WriteLine(el); Result: <Root>
<item id="text1" value="111" />
<item id="text2" value="222" />
<item id="text3" value="333" />
</Root> Option 3:using System.Xml;
using System.Xml.Serialization;
var dictionary = new Dictionary<string, int>
{
{ "text1", 111 },
{ "text2", 222 },
{ "text3", 333 }
};
string output;
XmlSerializer keySerializer = new XmlSerializer(typeof(string));
XmlSerializer valueSerializer = new XmlSerializer(typeof(int));
using var stringWriter = new StringWriter();
using XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter) { Formatting = Formatting.Indented };
foreach (var kvp in dictionary)
{
xmlWriter.WriteStartElement("item");
xmlWriter.WriteStartElement("key");
keySerializer.Serialize(xmlWriter, kvp.Key);
xmlWriter.WriteEndElement();
xmlWriter.WriteStartElement("value");
valueSerializer.Serialize(xmlWriter, kvp.Value);
xmlWriter.WriteEndElement();
xmlWriter.WriteEndElement();
}
output = stringWriter.ToString();
Console.WriteLine(output); Result: <item>
<key>
<string>text1</string>
</key>
<value>
<int>111</int>
</value>
</item>
<item>
<key>
<string>text2</string>
</key>
<value>
<int>222</int>
</value>
</item>
<item>
<key>
<string>text3</string>
</key>
<value>
<int>333</int>
</value>
</item> Here are some additional links that have other ways of doing this: |
Beta Was this translation helpful? Give feedback.
This has been the case for a long time as far as I can tell, check out some links below where people have been working around this issue since the early .NET days.
As for serialization, it is possible, it is just not as straight forward as JSON serialization, there are quite a few ways to do this, here are a few:
Option 1:
using System.Xml.Linq;
Result:
Option 2: