How to Serialize/Deserialize a Dictionary with Custom Keys Using JSON.Net

How can I serialize/deserialize a dictionary with custom keys using Json.Net?

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.

How can I deserialize JSON to a simple Dictionarystring,string in ASP.NET?

Json.NET does this...

string json = @"{""key1"":""value1"",""key2"":""value2""}";

var values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);

More examples: Serializing Collections with Json.NET

C# Deserializing a Dictionary(Enum,Enum),string with JSON.NET

A bit manual (and lacking decent error checking), but works for your specified json both serializing & deserializing

public class CustomDictionaryConverter : JsonConverter<Dictionary<(EnumType1 Enum1, EnumType2 Enum2), string>>
{
public override void WriteJson(JsonWriter writer, Dictionary<(EnumType1 Enum1, EnumType2 Enum2), string> value, JsonSerializer serializer)
{
writer.WriteStartObject();
foreach(var kv in value)
{
writer.WritePropertyName($"({kv.Key.Enum1.ToString()},{kv.Key.Enum2.ToString()})");
writer.WriteValue(kv.Value);
}
writer.WriteEndObject();
}

public override Dictionary<(EnumType1 Enum1, EnumType2 Enum2), string> ReadJson(
JsonReader reader
, Type objectType
, Dictionary<(EnumType1 Enum1, EnumType2 Enum2), string> existingValue
, bool hasExistingValue
, JsonSerializer serializer)
{
Dictionary<(EnumType1 Enum1, EnumType2 Enum2), string> tempdict = new Dictionary<(EnumType1 Enum1, EnumType2 Enum2), string>();
JObject jObject = JObject.Load(reader);
foreach(var kv in ((IEnumerable<KeyValuePair<string, JToken>>)jObject))
{
var keys = kv.Key.Replace("(","").Replace(")","").Split(",");
var key1 = Enum.Parse<EnumType1>(keys[0]);
var key2 = Enum.Parse<EnumType2>(keys[1]);
var value = kv.Value.ToString();
tempdict.Add((key1,key2),value);
}
return tempdict;
}
}

Live example: https://dotnetfiddle.net/w85HgK



Related Topics



Leave a reply



Submit