How can I serialize/deserialize a dictionary with custom keys using Json.Net?
.net, c#, json, json.net
Solution
This should do the trick:
Serialization:
JsonConvert.SerializeObject(expected.ToArray(), Formatting.Indented, jsonSerializerSettings);
By calling `expected.ToArray()` you're serializing an array of `KeyValuePair<MyClass, object>` objects rather than the dictionary.
Deserialization:
JsonConvert.DeserializeObject<KeyValuePair<IDataKey, object>[]>(output, jsonSerializerSettings).ToDictionary(kv => kv.Key, kv => kv.Value);
Here you deserialize the array and then retrieve the dictionary with `.ToDictionary(...)` call.
I'm not sure if the output meets your expectations, but surely it passes the equality assertion.
Problem
I have the following class, that I use as a key in a dictionary: ``` public class MyClass { private readonly string _property; public MyClass(string property) { _property = property; } public string Property { get { return _property; } } public override bool Equals(object obj) { MyClass other = obj as MyClass; if (other == null) return false; return _property == other._property; } public override int GetHashCode() { return _property.GetHashCode(); } } ``` The test I am running is here: ``` [Test] public void SerializeDictionaryWithCustomKeys() { IDictionary<MyClass, object> expected = new Dictionary<MyClass, object>(); expected.Add(new MyClass("sth"), 5.2); JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }; string output = JsonConvert.SerializeObject(expected, Formatting.Indented, jsonSerializerSettings); var actual = JsonConvert.DeserializeObject<IDictionary<MyClass, object>>(output, jsonSerializerSettings); CollectionAssert.AreEqual(expected, actual); } ``` The test fails, because Json.Net seems to be using the `ToString()` method on the dictionary keys, instead of serializing them properly. The resulting json from the test above is: ``` { "$type": "System.Collections.Generic.Dictionary`2[[RiskAnalytics.UnitTests.API.TestMarketContainerSerialisation+MyClass, RiskAnalytics.UnitTests],[System.Object, mscorlib]], mscorlib", "RiskAnalytics.UnitTests.API.TestMarketContainerSerialisation+MyClass": 5.2 } ``` which is clearly wrong. How can I get it to work?