Skip to content

Instantly share code, notes, and snippets.

@he-dev
Forked from petermorlion/DictionaryJsonConverter
Created March 27, 2018 16:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save he-dev/7dacd189427ceac2541916da911b6475 to your computer and use it in GitHub Desktop.
Save he-dev/7dacd189427ceac2541916da911b6475 to your computer and use it in GitHub Desktop.
Generic JsonConverter for JSON.NET and IDictionaries
// UPDATE!
// In Json.NET 7, a DictionaryKeyResolver was added.
// This might be able to fix the problem more elegantly.
// I haven't checked though.
public class DictionaryJsonConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var dictionary = (IDictionary)value;
writer.WriteStartArray();
foreach (var key in dictionary.Keys)
{
writer.WriteStartObject();
writer.WritePropertyName("Key");
serializer.Serialize(writer, key);
writer.WritePropertyName("Value");
serializer.Serialize(writer, dictionary[key]);
writer.WriteEndObject();
}
writer.WriteEndArray();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (!CanConvert(objectType))
throw new Exception(string.Format("This converter is not for {0}.", objectType));
var keyType = objectType.GetGenericArguments()[0];
var valueType = objectType.GetGenericArguments()[1];
var dictionaryType = typeof(Dictionary<,>).MakeGenericType(keyType, valueType);
var result = (IDictionary)Activator.CreateInstance(dictionaryType);
if (reader.TokenType == JsonToken.Null)
return null;
while (reader.Read())
{
if (reader.TokenType == JsonToken.EndArray)
{
return result;
}
if (reader.TokenType == JsonToken.StartObject)
{
AddObjectToDictionary(reader, result, serializer, keyType, valueType);
}
}
return result;
}
public override bool CanConvert(Type objectType)
{
return objectType.IsGenericType && (objectType.GetGenericTypeDefinition() == typeof(IDictionary<,>) || objectType.GetGenericTypeDefinition() == typeof(Dictionary<,>));
}
private void AddObjectToDictionary(JsonReader reader, IDictionary result, JsonSerializer serializer, Type keyType, Type valueType)
{
object key = null;
object value = null;
while (reader.Read())
{
if (reader.TokenType == JsonToken.EndObject && key != null)
{
result.Add(key, value);
return;
}
var propertyName = reader.Value.ToString();
if (propertyName == "Key")
{
reader.Read();
key = serializer.Deserialize(reader, keyType);
}
else if (propertyName == "Value")
{
reader.Read();
value = serializer.Deserialize(reader, valueType);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment