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 class CustomJsonConverter : Newtonsoft.Json.JsonConverter
bool Disabled { get { return disabled; } set { disabled = value; } }
public override bool CanWrite { get { return !Disabled; } }
public override bool CanRead { get { return !Disabled; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
using (new PushValue<bool>(true, () => Disabled, val => Disabled = val))
using (new PushValue<PreserveReferencesHandling>(PreserveReferencesHandling.Objects, () => serializer.PreserveReferencesHandling, val => serializer.PreserveReferencesHandling = val))
using (new PushValue<DefaultValueHandling>(DefaultValueHandling.Ignore, () => serializer.DefaultValueHandling, val => serializer.DefaultValueHandling = val))
using (new PushValue<NullValueHandling>(NullValueHandling.Ignore, () => serializer.NullValueHandling, val => serializer.NullValueHandling = val))
serializer.Serialize(writer, value);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
if (reader.TokenType == JsonToken.Null)
using (new PushValue<bool>(true, () => Disabled, val => Disabled = val))
using (new PushValue<PreserveReferencesHandling>(PreserveReferencesHandling.Objects, () => serializer.PreserveReferencesHandling, val => serializer.PreserveReferencesHandling = val))
using (new PushValue<DefaultValueHandling>(DefaultValueHandling.Ignore, () => serializer.DefaultValueHandling, val => serializer.DefaultValueHandling = val))
using (new PushValue<NullValueHandling>(NullValueHandling.Ignore, () => serializer.NullValueHandling, val => serializer.NullValueHandling = val))
return serializer.Deserialize(reader, objectType);
public override bool CanConvert(Type objectType)
throw new NotImplementedException();
public struct PushValue<T> : IDisposable
public PushValue(T value, Func<T> getValue, Action<T> setValue)
if (getValue == null || setValue == null)
throw new ArgumentNullException();
this.setValue = setValue;
this.oldValue = getValue();
[JsonConverter(typeof(CustomJsonConverter))]
public abstract class ModelBase : IModelBase
public string ID { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime ModifiedAt { get; set; }
public class CustomerModel : ModelBase
public string Name { get; set; }
public UserModel CreatedBy { get; set; }
public UserModel ModifiedBy { get; set; }
public class UserModel : ModelBase
public string Name { get; set; }
public UserModel CreatedBy { get; set; }
public UserModel ModifiedBy { get; set; }
public interface IModelBase
public static void Test()
static object Deserialize(Stream streamFromWebAPICall, Type objectType)
using (var sr = new StreamReader(streamFromWebAPICall))
using (var jtr = new JsonTextReader(sr))
var settings = new JsonSerializerSettings
DefaultValueHandling = DefaultValueHandling.Ignore,
NullValueHandling = NullValueHandling.Ignore,
var js = JsonSerializer.CreateDefault(settings);
return js.Deserialize(jtr, objectType);
static void TestDeserialize()
var inputJson = GetInputJson();
var streamFromWebAPICall = new MemoryStream(Encoding.UTF8.GetBytes(inputJson));
var root = (List<CustomerModel>)Deserialize(streamFromWebAPICall, typeof(List<CustomerModel>));
var settings = new JsonSerializerSettings
DefaultValueHandling = DefaultValueHandling.Ignore,
NullValueHandling = NullValueHandling.Ignore,
var outputJson = JsonConvert.SerializeObject(root, Formatting.Indented, settings);
Console.WriteLine("Round-tripped {0}:", root);
Console.WriteLine(outputJson);
Assert.IsTrue(JToken.DeepEquals(JToken.Parse(inputJson), JToken.Parse(outputJson)));
Assert.IsTrue(root.Count == 2 && root[1].CreatedBy == root[0].CreatedBy && root[1].ModifiedBy == root[0].CreatedBy);
static string GetInputJson()
""CreatedAt"": ""2019-02-06T00:00:04"",
""ModifiedAt"": ""2019-02-06T00:20:12""
""CreatedAt"": ""2019-02-06T00:10:00"",
""ModifiedAt"": ""2019-02-06T00:10:00""
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: ");