Ron Beyer Ron Beyer - 27 days ago 10
C# Question

Deserialize JSON Dictionary with StringComparer

I'm trying to serialize/deserialize a dictionary, the problem is that I create the dictionary with a

StringComparer.OrdinalIgnoreCase
comparer.

Here is a code snippet of the problem I'm experiencing:

var dict = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);

dict["x"] = new Dictionary<string, string>();
dict["x"]["y"] = "something";

var serialized = JsonConvert.SerializeObject(dict);

var unSerialized = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(serialized);

Console.WriteLine((dict.Comparer == unSerialized.Comparer ? "Same" : "Different"));


(.NET Fiddle - Try It)

Prints out the following on the console:

Different


Obviously the JSON serializer doesn't serialize the Comparer that I set when I create the dictionary, but the issue is that I can't set the Comparer after the fact since
Dictionary<TKey, TValue>.Comparer
is read-only.

I'm sure it has to do with some custom
JsonSerializerSetting
but I can't seem to figure out how to intercept the collection creation and return a dictionary with a different comparer.

Answer Source

You can also populate an existing object with PopulateObject:

var dict = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);

dict["x"] = new Dictionary<string, string>();
dict["x"]["y"] = "something";

var json = JsonConvert.SerializeObject(dict);


var result =  new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
JsonConvert.PopulateObject(json, result);

Console.WriteLine(result["x"]["y"]);
Console.WriteLine(result.Comparer == dict.Comparer ? "Same" : "Diff");

Output:

something
Same