using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections.Specialized;
using System.Web.Routing;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using System.Web.SessionState;
[JsonConverter(typeof(ObjectToArrayConverter))]
public abstract class SettingBase
public class ObjectToArrayConverter : JsonConverter
public override bool CanConvert(Type objectType)
throw new NotImplementedException();
static bool ShouldSkip(JsonProperty property)
return property.Ignored || !property.Readable || !property.Writable;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
var type = value.GetType();
var contract = serializer.ContractResolver.ResolveContract(type) as JsonObjectContract;
throw new JsonSerializationException("invalid type " + type.FullName);
var list = contract.Properties.Where(p => !ShouldSkip(p)).Select(p => p.ValueProvider.GetValue(value));
serializer.Serialize(writer, list);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
if (reader.TokenType == JsonToken.Null)
var token = JToken.Load(reader);
if (token.Type != JTokenType.Array)
throw new JsonSerializationException("token was not an array");
var contract = serializer.ContractResolver.ResolveContract(objectType) as JsonObjectContract;
throw new JsonSerializationException("invalid type " + objectType.FullName);
var value = existingValue ?? contract.DefaultCreator();
foreach (var pair in contract.Properties.Where(p => !ShouldSkip(p)).Zip(token, (p, v) => new { Value = v, Property = p }))
var propertyValue = pair.Value.ToObject(pair.Property.PropertyType, serializer);
pair.Property.ValueProvider.SetValue(value, propertyValue);
public class SettingA : SettingBase
[JsonProperty(Order = 1)]
public int Property1 { get; set; }
[JsonProperty(Order = 2)]
public double Property2 { get; set; }
public class SettingB : SettingBase
[JsonProperty(Order = 1)]
public int Code { get; set; }
[JsonProperty(Order = 2)]
public double ColorTemperature { get; set; }
[JsonProperty(Order = 3)]
public double GammaCorrection { get; set; }
[JsonProperty(Order = 4)]
public string Name { get; set; }
public class SettingsTable<TSettings> where TSettings : SettingBase
public SettingsTable() { this.Value = new List<TSettings>(); }
public List<TSettings> Value { get; set; }
public string Type { get; set; }
[JsonProperty("readonly")]
public int Readonly { get; set; }
public SettingsSet() { this.OtherSettings = new Dictionary<string, JToken>(); }
public SettingsTable<SettingA> SettingA { get; set; }
public SettingsTable<SettingB> SettingB { get; set; }
public Dictionary<string, JToken> OtherSettings { get; set; }
public static void Test()
var settingsSet = JsonConvert.DeserializeObject<SettingsSet>(json);
var json2 = JsonConvert.SerializeObject(settingsSet, Formatting.Indented);
Console.WriteLine("Reserialized {0}", settingsSet);
Console.WriteLine(json2);
""SettingA"": { ""value"": [
], ""type"": ""array"", ""readonly"": 1},
""SettingB"": { ""value"": [
[ 3, 3320, -0.6, ""Auto WB"" ],
[ 7, 3200, 0, ""Tungsten"" ],
[ 7, 4300, 0, ""Fluorescent"" ],
[ 7, 5600, 0, ""Daylight"" ],
[ 7, 7000, 0, ""Daylight cool"" ]
], ""type"": ""array"", ""readonly"": 1},
""SettingC"": { ""value"": [
], ""type"": ""array"", ""readonly"": 1},
public static void Main()
Console.WriteLine("Json.NET version: " + typeof(JsonSerializer).Assembly.FullName);