Serialize Class containing Dictionary member
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Serializing a C# class with a dictionary property is common in APIs, caching layers, and configuration storage. Most cases work out of the box, but edge cases appear when key types are not strings or when backward compatibility is required. A robust approach combines clear model design, explicit serializer options, and predictable versioning rules.
Basic Serialization with System.Text.Json
For dictionaries with string keys, System.Text.Json usually handles serialization and deserialization automatically.
This is the best starting point for most modern .NET applications.
Non-String Dictionary Keys
JSON object property names are strings. When your dictionary key type is an enum, integer, or custom type, conversion behavior matters. For many primitive keys, serialization works through string conversion, but custom key types may need explicit converters.
Explicit converters keep wire format predictable and easier to maintain.
Designing for Compatibility
When serialized data is persisted long-term, schema evolution becomes important. Dictionary keys and values can change over time, so plan for missing entries and optional values.
Practical rules:
- Initialize dictionary properties to empty instances.
- Avoid null dictionary references in domain models.
- Keep stable key naming conventions.
- Add migration code when key names change.
You can also isolate transport models from domain models. Convert between them so storage format can evolve without breaking internal logic.
Newtonsoft.Json Interoperability
Some teams still use Newtonsoft.Json, especially in legacy codebases. It handles dictionary serialization well and includes rich converter support. If you mix serializers in one solution, verify that both produce compatible JSON for shared payloads.
For greenfield .NET applications, System.Text.Json is usually preferred for performance and built-in framework integration. For specialized polymorphic cases, evaluate feature needs before standardizing.
If dictionary content comes from untrusted sources, add value validation after deserialization. Large payloads, unexpected key patterns, or unsupported numeric formats can still pass parsing but fail business rules. A dedicated validation layer keeps serialization code simple and prevents bad state from entering your core domain model.
Testing Strategy
Add round-trip tests for representative samples, including:
- Empty dictionary.
- Missing dictionary field.
- Unexpected keys.
- Large dictionary size.
Round-trip assertions catch subtle converter issues early and prevent production regressions when serializer options change.
Common Pitfalls
A common pitfall is assuming custom object keys in dictionaries serialize naturally to stable JSON property names. Without explicit conversion rules, outputs may be fragile or unreadable.
Another issue is leaving dictionary properties nullable and then forgetting null checks after deserialization. Prefer non-null defaults to simplify business logic.
Developers also change key names in code without migration support for persisted payloads. This can silently lose access to stored values. Keep key evolution deliberate and version-aware.
Finally, using different serializers across services without compatibility tests can create subtle parsing mismatches. Validate payloads end to end when crossing service boundaries.
Summary
- String-key dictionaries serialize easily with
System.Text.Json. - Non-string keys often need explicit converter strategy.
- Initialize dictionary properties to avoid null handling bugs.
- Plan schema evolution for persisted dictionary payloads.
- Add round-trip tests to protect serialization behavior over time.
Related reading
- Serializing class instance to JSON
- Session graph is empty
- Set Collection - Insert multiple elements
- Set Cover or Hitting Set; Numpy, Least element combinations to make up full set
- Serialize Property as Xml Attribute in Element
- Server.UrlEncode vs. HttpUtility.UrlEncode
- Set inputType for an EditText Programmatically?
- Set markers for individual points on a line

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.