TL;DR Json.NET can serialize and deserialize dictionaries with simple keys like integers or strings. It can serialize, but not deserialize dictionaries with more complex keys.
Longer version: Json.NET uses ToString() to convert a dictionary key to JSON field identifier. A simple case works like this:
var dict = new Dictionary<int, string> { {10, "ten"}, {42, "forty two"} }; var json = JsonConvert.SerializeObject(dict); Console.WriteLine(json); // prints {"10":"ten","42":"forty two"} var deserialized = JsonConvert.DeserializeObject<Dictionary<int, string>>(json); // gets your dictionary back
The dictionary value can be of any complex type: normal serialization rules apply.
var dict = new Dictionary<int, Tuple<int, string>>() { {10, Tuple.Create(10, "ten")}, {42, Tuple.Create(42, "forty two")}, }; Console.WriteLine(); var json = JsonConvert.SerializeObject(dict); Console.WriteLine(json); // {"10":{"Item1":10,"Item2":"ten"},"42":{"Item1":42,"Item2":"forty two"}} var deserialized = JsonConvert.DeserializeObject<Dictionary<int, Tuple<int, string>>>(json);
However, Json.NET uses ToString()
to generate dictionary keys:
var dict = new Dictionary<Tuple<int, int>, string> { { Tuple.Create(10,20), "ten-twenty" }, { Tuple.Create(5,3), "five-three" }, }; var json = JsonConvert.SerializeObject(dict); Console.WriteLine(json); // {"(10, 20)":"ten-twenty","(5, 3)":"five-three"} var deserialized = JsonConvert.DeserializeObject<Dictionary<Tuple<int, int>, string>>(json); // blows up
It is even possible to trick Json.NET into generating duplicate keys (which appears to be technically valid JSON):
struct CustomKey { private readonly int _val; public CustomKey(int val) { _val = val; } public override string ToString() { return "CustomKey"; } public override int GetHashCode() { return _val.GetHashCode(); } public override bool Equals(object obj) { if (!(obj is CustomKey)) return false; return _val == ((CustomKey)obj)._val; } } var dict = new Dictionary<CustomKey, string> { {new CustomKey(10), "ten"}, {new CustomKey(42), "forty two"} }; var json = JsonConvert.SerializeObject(dict); Console.WriteLine(json); // {"CustomKey":"ten","CustomKey":"forty two"} var deserialized = JsonConvert.DeserializeObject<Dictionary<CustomKey, string>>(json); // blows up
Well, no one is perfect 🙂