using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
public class UntypedToTypedValueConverter : JsonConverter
public override bool CanConvert(Type objectType)
throw new NotImplementedException("This converter should only be applied directly via ItemConverterType, not added to JsonSerializer.Converters");
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
Console.WriteLine("ReadJson Called");
if (reader.TokenType == JsonToken.Null)
var value = serializer.Deserialize(reader, objectType);
if (value is TypeWrapper)
return ((TypeWrapper)value).ObjectValue;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
Console.WriteLine("WriteJson Called");
if (serializer.TypeNameHandling == TypeNameHandling.None)
Console.WriteLine("ObjectItemConverter used when serializer.TypeNameHandling == TypeNameHandling.None");
serializer.Serialize(writer, value);
else if (value is string)
writer.WriteValue((string)value);
writer.WriteValue((bool)value);
var contract = serializer.ContractResolver.ResolveContract(value.GetType());
if (contract is JsonPrimitiveContract)
var wrapper = TypeWrapper.CreateWrapper(value);
serializer.Serialize(writer, wrapper, typeof(object));
serializer.Serialize(writer, value);
abstract class TypeWrapper
protected TypeWrapper() { }
public abstract object ObjectValue { get; }
public static TypeWrapper CreateWrapper<T>(T value)
return new TypeWrapper<T>();
var type = value.GetType();
return new TypeWrapper<T>(value);
return (TypeWrapper)Activator.CreateInstance(typeof(TypeWrapper<>).MakeGenericType(type), value);
sealed class TypeWrapper<T> : TypeWrapper
public TypeWrapper() : base() { }
public TypeWrapper(T value)
public override object ObjectValue { get { return Value; } }
public T Value { get; set; }
[JsonProperty(ItemConverterType = typeof(UntypedToTypedValueConverter))]
public object[] Items { get; set; }
public static void Main()
Console.WriteLine("Json.NET version: " + typeof(JsonSerializer).Assembly.FullName);
var root = new RootObject { Items = new object[] { 1, 1L, int.MaxValue, long.MaxValue } };
var settings = new JsonSerializerSettings
Formatting = Formatting.Indented,
TypeNameHandling = TypeNameHandling.Auto,
TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
var json = JsonConvert.SerializeObject(root, settings);
var root2 = JsonConvert.DeserializeObject<RootObject>(json, settings);
if (!root.Items.SequenceEqual(root2.Items))
throw new InvalidOperationException("!root.Items.SequenceEqual(root2.Items)");
if (!root.Items.Select(i => i.GetType()).SequenceEqual(root2.Items.Select(i => i.GetType())))
throw new InvalidOperationException("!root.Items.Select(i => i.GetType()).SequenceEqual(root2.Items.Select(i => i.GetType()))");
Console.WriteLine("Json deserialized successfully.");