Motivation: Wanted convenience of a Dictionary on the server side MVC controller (for some key look-up based logic), yet send the same list of objects down to Knockout Ajax client, which most readily consumes lists as Javascript object arrays.
Could’ve just exposed the List
using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; namespace YouNameIt { using CartItemDict = Dictionary<long, CartItemDto>; //reverse of this: https://stackoverflow.com/questions/24759181/deserializing-a-json-dictionaryint-customtype-to-listcustomtype //adapted from here: https://james.newtonking.com/json/help/index.html?topic=html/CustomJsonConverter.htm public class DictToListConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType == typeof (Dictionary<object, object>); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException(); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var t = JToken.FromObject(value); if (t.Type != JTokenType.Object) { t.WriteTo(writer); } else { var o = (JObject) t; var values = o.Properties().Select(p => p.Value).ToList(); (new JArray(values)).WriteTo(writer); } } } public class CartDto { [JsonConverter(typeof(DictToListConverter))] public CartItemDict Items { get; set; } [DataType(DataType.Currency)] public decimal TotalPrice { get; private set; } } public class CartItemDto : VariantDto { public long CartItemId { get; private set; } public int Quantity { get; private set; } [DataType(DataType.Currency)] public decimal UnitPrice { get; private set; } [DataType(DataType.Currency)] public decimal LinePrice { get; private set; } private List _addons; public List Addons { get { return _addons ?? (_addons = new List()); } } } }