using System.Collections;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
internal class IntToBoolConverter : JsonConverter
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
writer.WriteValue(((bool)value) ? "1" : "0");
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.Boolean)
public override bool CanConvert(Type objectType)
return objectType == typeof(bool) || objectType == typeof(bool?);
public class ActionTypeConverter : StringEnumConverter
public ActionTypeConverter()
this.CamelCaseText = true;
public abstract class ActionResult
public class OpenActionResult : ActionResult
public string property1 { get; set; }
public string property2 { get; set; }
public DateTime? property3 { get; set; }
public string property4 { get; set; }
public bool property5 { get; set; }
[JsonConverter(typeof(ActionConverter))]
readonly static Dictionary<Type, System.Type> typeToSystemType;
readonly static Dictionary<System.Type, Type> systemTypeToType;
typeToSystemType = new Dictionary<Type, System.Type>
{ Type.Open, typeof(OpenActionResult) },
systemTypeToType = typeToSystemType.ToDictionary(p => p.Value, p => p.Key);
public static Type SystemTypeToType(System.Type systemType)
return systemTypeToType[systemType];
public static System.Type TypeToSystemType(Type type)
return typeToSystemType[type];
public string Id { get; set; }
public string Name { get; set; }
[JsonConverter(typeof(IntToBoolConverter))]
public bool Active { get; set; }
[JsonConverter(typeof(ActionTypeConverter))]
public Type ActionType { get; set; }
public ActionResult Result { get; set; }
class ActionConverter : JsonConverter
public override bool CanConvert(Type objectType)
throw new NotImplementedException();
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
if (reader.TokenType == JsonToken.Null)
var obj = JObject.Load(reader);
var contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(objectType);
var action = existingValue as Action ?? (Action)contract.DefaultCreator();
var result = obj.GetValue("Result", StringComparison.OrdinalIgnoreCase).RemoveFromLowestPossibleParent();
using (var subReader = obj.CreateReader())
serializer.Populate(subReader, action);
action.Result = (ActionResult)result.ToObject(Action.TypeToSystemType(action.ActionType));
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
throw new NotImplementedException();
public static class JsonExtensions
public static JToken RemoveFromLowestPossibleParent(this JToken node)
var contained = node.AncestorsAndSelf().Where(t => t.Parent is JContainer && t.Parent.Type != JTokenType.Property).FirstOrDefault();
if (node.Parent is JProperty)
((JProperty)node.Parent).Value = null;
""id"":""aa0832f0508bb580ce7f0506132c1c13"",
""property2"":""123.123"",
""property3"":""2016-07-16T23:00:00"",
public static void Test()
Console.WriteLine("Original JSON: ");
var action = JsonConvert.DeserializeObject<Action>(json);
var json2 = JsonConvert.SerializeObject(action, Formatting.Indented);
Console.WriteLine("Re-serialized JSON: ");
Console.WriteLine(json2);
if (JToken.DeepEquals(JToken.Parse(json), JToken.Parse(json2)))
Console.WriteLine("Original and re-serialized JSON are equivalent.");
throw new InvalidOperationException("Original and re-serialized JSON are NOT equivalent.");
var action2 = JsonConvert.DeserializeObject<Action>(json2);
var json3 = JsonConvert.SerializeObject(action, Formatting.Indented);
Console.WriteLine("Re-re-serialized JSON: ");
Console.WriteLine(json3);
public static void Main()
Console.WriteLine("Environment version: " + Environment.Version);
Console.WriteLine("{0} version: {1}", typeof(JsonSerializer).Namespace, typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");