using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
public string Name {get; set;}
public Dictionary<string,Position> Positions {get; set;}
public string Ticker {get; set;}
public decimal Size {get; set;}
public class PositionDictionaryConverter : DictionaryAsListConverter<Position>
protected override string GetKey(Position position) { return position.Ticker; }
public abstract class DictionaryAsListConverter<TValue> : JsonConverter
protected abstract string GetKey(TValue value);
public override bool CanConvert(Type objectType)
return typeof(Dictionary<string, TValue>).IsAssignableFrom(objectType);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
if (reader.MoveToContent().TokenType == JsonToken.Null)
var list = serializer.Deserialize<List<TValue>>(reader);
var dictionary = (IDictionary<string, TValue>)(existingValue ?? serializer.ContractResolver.ResolveContract(objectType).DefaultCreator());
foreach (var item in list)
dictionary.Add(GetKey(item), item);
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
serializer.Serialize(writer, ((IDictionary<string, TValue>)value).Values);
public static partial class JsonExtensions
public static JsonReader MoveToContent(this JsonReader reader)
if (reader.TokenType == JsonToken.None)
while (reader.TokenType == JsonToken.Comment && reader.Read())
public static void Test()
var inputJson = GetJson();
var settings = new JsonSerializerSettings
Converters = { new PositionDictionaryConverter() },
var portfolio = JsonConvert.DeserializeObject<Portfolio>(inputJson, settings);
var json = JsonConvert.SerializeObject(portfolio, Formatting.Indented, settings);
Console.WriteLine("Deserialized and re-serialized {0}", portfolio);
Assert.IsTrue(JToken.DeepEquals(JToken.Parse(json), JToken.Parse(inputJson)));
public static void Main()
Console.WriteLine("Environment version: " + Environment.Version);
Console.WriteLine("Json.NET version: " + typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");