Created
July 16, 2017 01:49
-
-
Save NullEntity/2f305076d81e6c1592b853f9b2a060ca to your computer and use it in GitHub Desktop.
Saves a dictionary as key/value pairs. Importantly, it uses JsonConverters on the dictionary keys which the default JsonSerializer doesn't do.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Linq; | |
using Newtonsoft.Json; | |
public class CustomDictionaryConverter : JsonConverter | |
{ | |
public override bool CanConvert(Type objectType) | |
{ | |
return typeof(IDictionary).IsAssignableFrom(objectType) || | |
TypeImplementsGenericInterface(objectType, typeof(IDictionary<,>)); | |
} | |
private static bool TypeImplementsGenericInterface(Type concreteType, Type interfaceType) | |
{ | |
return concreteType.GetInterfaces() | |
.Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == interfaceType); | |
} | |
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) | |
{ | |
var dictionaryTypeArguments = objectType.GetGenericArguments(); | |
var keyValuePairType = typeof(KeyValuePair<,>).MakeGenericType(dictionaryTypeArguments[0], dictionaryTypeArguments[1]); | |
var keyValuePairKeyPropertyInfo = keyValuePairType.GetProperty("Key"); | |
var keyValuePairValuePropertyInfo = keyValuePairType.GetProperty("Value"); | |
var keyValuePairListType = typeof(IList<>).MakeGenericType(keyValuePairType); | |
var keyValuePairList = (IEnumerable) serializer.Deserialize(reader, keyValuePairListType); | |
var dictionaryType = | |
typeof(Dictionary<,>).MakeGenericType(dictionaryTypeArguments[0], dictionaryTypeArguments[1]); | |
var dictionaryAddMethodInfo = dictionaryType.GetMethod("Add", new []{ dictionaryTypeArguments[0], dictionaryTypeArguments[1] }); | |
var dictionary = Activator.CreateInstance(dictionaryType); | |
foreach (var pair in keyValuePairList) | |
{ | |
var key = keyValuePairKeyPropertyInfo.GetValue(pair, null); | |
var value = keyValuePairValuePropertyInfo.GetValue(pair, null); | |
dictionaryAddMethodInfo.Invoke(dictionary, new [] { key, value }); | |
} | |
return dictionary; | |
} | |
// write the dictionary as key/value pairs | |
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) | |
{ | |
var type = value.GetType(); | |
var keys = (IEnumerable) type.GetProperty("Keys").GetValue(value, null); | |
var values = (IEnumerable) type.GetProperty("Values").GetValue(value, null); | |
var valueEnumerator = values.GetEnumerator(); | |
writer.WriteStartArray(); | |
foreach (var key in keys) | |
{ | |
valueEnumerator.MoveNext(); | |
writer.WriteStartObject(); | |
writer.WritePropertyName("key"); | |
serializer.Serialize(writer, key); | |
writer.WritePropertyName("value"); | |
serializer.Serialize(writer, valueEnumerator.Current); | |
writer.WriteEndObject(); | |
} | |
writer.WriteEndArray(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment