using System.Collections.Generic;
using Newtonsoft.Json.Linq;
public static void Main()
ChildDictionary dict = new ChildDictionary();
dict.Add(new Employee { Id = 22, Name = "Joe", HireDate = new DateTime(2012, 4, 17) }, 1923.07);
dict.Add(new Employee { Id = 45, Name = "Fred", HireDate = new DateTime(2010, 8, 22) }, 1415.25);
string json = JsonConvert.SerializeObject(dict, Formatting.Indented);
dict = JsonConvert.DeserializeObject<ChildDictionary>(json);
Console.WriteLine("Name: " + dict.Name);
foreach (var kvp in dict)
Console.WriteLine("Employee Id: " + kvp.Key.Id);
Console.WriteLine("Employee Name: " + kvp.Key.Name);
Console.WriteLine("Employee Hire Date: " + kvp.Key.HireDate);
Console.WriteLine("Amount: " + kvp.Value);
[JsonConverter(typeof(ComplexDictionaryConverter<Employee, double>))]
public class ChildDictionary : Dictionary<Employee, double>
public string Name { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public DateTime HireDate { get; set; }
public class ComplexDictionaryConverter<K,V> : JsonConverter
public override bool CanConvert(Type objectType)
return (objectType.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDictionary<K,V>)));
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
JObject obj = new JObject();
foreach (PropertyInfo prop in GetReadWriteProperties(value.GetType()))
object val = prop.GetValue(value);
obj.Add(prop.Name, val != null ? JToken.FromObject(val, serializer) : new JValue(val));
JArray array = new JArray();
foreach (var kvp in (IDictionary<K, V>)value)
JObject item = new JObject();
item.Add("Key", JToken.FromObject(kvp.Key, serializer));
item.Add("Value", kvp.Value != null ? JToken.FromObject(kvp.Value, serializer) : new JValue(kvp.Value));
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
JObject obj = JObject.Load(reader);
IDictionary<K, V> dict = (IDictionary<K, V>)Activator.CreateInstance(objectType);
foreach (PropertyInfo prop in GetReadWriteProperties(objectType))
JToken token = obj[prop.Name];
object val = token != null ? token.ToObject(prop.PropertyType, serializer) : null;
prop.SetValue(dict, val);
JArray array = (JArray)obj["KVPs"];
foreach (JObject kvp in array.Children<JObject>())
K key = kvp["Key"].ToObject<K>(serializer);
V val = kvp["Value"].ToObject<V>(serializer);
private IEnumerable<PropertyInfo> GetReadWriteProperties(Type type)
return type.GetProperties().Where(p => p.CanRead && p.CanWrite && !p.GetIndexParameters().Any());