-
-
Save he-dev/7dacd189427ceac2541916da911b6475 to your computer and use it in GitHub Desktop.
Generic JsonConverter for JSON.NET and IDictionaries
This file contains 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
// 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