.NET
XML serialization
dictionary serialization
C# programming
software development

Why isn't there an XML-serializable dictionary in .NET?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

XmlSerializer in .NET is built around a stable, schema-like mapping between public members and XML elements. Dictionary<TKey, TValue> does not fit that model cleanly, which is why there is no simple built-in "XML-serializable dictionary" type that works automatically the same way arrays and plain objects do.

Why Dictionaries Are Awkward For XmlSerializer

XmlSerializer wants a predictable element structure. A dictionary is more complicated because:

  • keys are data, not fixed member names
  • keys may not be valid XML element names
  • ordering is not the logical identity of the structure
  • key and value types can vary in serialization difficulty

In XML, a dictionary-like structure usually has to be represented as repeated entries, not as arbitrary dynamic element names.

That is why something like this:

csharp
1public class Settings
2{
3    public Dictionary<string, string> Values { get; set; } = new();
4}

does not serialize nicely with plain XmlSerializer out of the box.

The serializer was designed for object graphs that look more like classes and arrays than maps.

XML Needs An Explicit Shape

A dictionary needs an XML representation such as:

xml
1<Settings>
2  <Values>
3    <Entry>
4      <Key>Theme</Key>
5      <Value>Dark</Value>
6    </Entry>
7    <Entry>
8      <Key>Language</Key>
9      <Value>en</Value>
10    </Entry>
11  </Values>
12</Settings>

That shape is perfectly reasonable, but notice what happened: the dictionary stopped being "magic" and became a list of key-value objects. That is exactly the kind of explicit structure XmlSerializer prefers.

A Common Solution: Serialize A List Of Entries

One practical pattern is to expose a serializable list and convert it to a dictionary in code.

csharp
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Linq;
5using System.Xml.Serialization;
6
7public class SettingEntry
8{
9    public string Key { get; set; } = string.Empty;
10    public string Value { get; set; } = string.Empty;
11}
12
13public class Settings
14{
15    public List<SettingEntry> Values { get; set; } = new();
16
17    public Dictionary<string, string> ToDictionary() =>
18        Values.ToDictionary(x => x.Key, x => x.Value);
19}
20
21var settings = new Settings
22{
23    Values = new List<SettingEntry>
24    {
25        new SettingEntry { Key = "Theme", Value = "Dark" },
26        new SettingEntry { Key = "Language", Value = "en" }
27    }
28};
29
30var serializer = new XmlSerializer(typeof(Settings));
31using var writer = new StringWriter();
32serializer.Serialize(writer, settings);
33Console.WriteLine(writer.ToString());

This approach is boring in a good way. It gives XML an explicit schema and keeps the runtime representation flexible.

Another Option: Implement IXmlSerializable

If you really want dictionary-like behavior during XML serialization, you can write the conversion yourself.

csharp
1using System.Collections.Generic;
2using System.Xml;
3using System.Xml.Schema;
4using System.Xml.Serialization;
5
6public class XmlDictionary : Dictionary<string, string>, IXmlSerializable
7{
8    public XmlSchema? GetSchema() => null;
9
10    public void ReadXml(XmlReader reader)
11    {
12        reader.ReadStartElement();
13        while (reader.NodeType != XmlNodeType.EndElement)
14        {
15            var key = reader.GetAttribute("Key") ?? string.Empty;
16            var value = reader.ReadElementContentAsString();
17            this[key] = value;
18        }
19        reader.ReadEndElement();
20    }
21
22    public void WriteXml(XmlWriter writer)
23    {
24        foreach (var pair in this)
25        {
26            writer.WriteStartElement("Entry");
27            writer.WriteAttributeString("Key", pair.Key);
28            writer.WriteString(pair.Value);
29            writer.WriteEndElement();
30        }
31    }
32}

This works, but it is more maintenance-heavy than a simple list-of-entries model. You own the XML contract completely.

Why .NET Did Not Hide This Automatically

The absence of a universal built-in solution is not really an omission. It is a design tradeoff.

Questions a built-in XML dictionary would have to answer include:

  • Should keys become element names or child values
  • How should non-string keys be represented
  • What should happen when key order changes
  • How should schemas be generated

There is no one representation that is obviously correct for every XML contract. Rather than pick a surprising default, XmlSerializer leaves that choice to the application.

Use Another Serializer When Appropriate

If the contract does not have to be XML, JSON serializers handle dictionaries much more naturally. Even within .NET, other serializers such as DataContractSerializer can support dictionary-like data better for some scenarios.

So the real question is often not "why is this missing" but "is XmlSerializer the right tool for this payload shape."

If you must interoperate with an existing XML schema, custom mapping is usually unavoidable anyway.

Common Pitfalls

The biggest mistake is expecting Dictionary<TKey, TValue> to serialize cleanly with XmlSerializer the same way a list or plain object does. XML needs a more explicit shape.

Another mistake is trying to use arbitrary dictionary keys as XML element names. Not every key is a valid or sensible XML tag name.

People also underestimate how much XML contracts depend on schema stability. A dictionary is often too dynamic for the serializer's default model.

Finally, writing a custom XML dictionary can be correct, but it adds complexity quickly. If a list of entries is good enough, it is usually the safer option.

Summary

  • 'XmlSerializer prefers fixed, schema-like object shapes, not dynamic map semantics.'
  • Dictionaries do not have one obvious XML representation, which is why no universal built-in solution exists.
  • A list of serializable key-value entries is the simplest practical workaround.
  • 'IXmlSerializable gives full control when you need custom XML output.'
  • If XML is not mandatory, another serializer may fit dictionary data more naturally.

Course illustration
Course illustration

All Rights Reserved.