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 string Name { get; set; }
public string Language { get; set; }
public List<Actor> Actors { get; set; }
public string Name { get; set; }
public class IgnoreCollectionTypeConverter : JsonConverter
public IgnoreCollectionTypeConverter() { }
public IgnoreCollectionTypeConverter(Type ItemConverterType)
this.ItemConverterType = ItemConverterType;
public Type ItemConverterType { get; set; }
public override bool CanConvert(Type objectType)
return objectType.GetCollectItemTypes().Count() == 1 && !objectType.IsDictionary() && !objectType.IsArray;
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
if (!CanConvert(objectType))
throw new JsonSerializationException(string.Format("Invalid type \"{0}\"", objectType));
if (reader.TokenType == JsonToken.Null)
var token = JToken.Load(reader);
var itemConverter = (ItemConverterType == null ? null : (JsonConverter)Activator.CreateInstance(ItemConverterType, true));
if (itemConverter != null)
serializer.Converters.Add(itemConverter);
return ToCollection(token, objectType, existingValue, serializer);
if (itemConverter != null)
serializer.Converters.RemoveLast(itemConverter);
private static object ToCollection(JToken token, Type collectionType, object existingValue, JsonSerializer serializer)
if (token == null || token.Type == JTokenType.Null)
else if (token.Type == JTokenType.Array)
existingValue = serializer.DefaultCreate<object>(collectionType, existingValue);
token.PopulateObject(existingValue, serializer);
else if (token.Type == JTokenType.Object)
var values = token["$values"];
return ToCollection(values, collectionType, existingValue, serializer);
throw new JsonSerializationException("Unknown token type: " + token.ToString());
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 T DefaultCreate<T>(this JsonSerializer serializer, Type objectType, object existingValue)
throw new ArgumentNullException();
return (T)serializer.ContractResolver.ResolveContract(objectType).DefaultCreator();
public static void PopulateObject(this JToken obj, object target, JsonSerializer serializer)
throw new NullReferenceException();
using (var reader = obj.CreateReader())
serializer.Populate(reader, target);
public static class TypeExtensions
public static IEnumerable<Type> GetInterfacesAndSelf(this Type type)
throw new ArgumentNullException();
return new[] { type }.Concat(type.GetInterfaces());
return type.GetInterfaces();
public static IEnumerable<Type> GetCollectItemTypes(this Type type)
foreach (Type intType in type.GetInterfacesAndSelf())
if (intType.IsGenericType
&& intType.GetGenericTypeDefinition() == typeof(ICollection<>))
yield return intType.GetGenericArguments()[0];
public static bool IsDictionary(this Type type)
if (typeof(IDictionary).IsAssignableFrom(type))
foreach (Type intType in type.GetInterfacesAndSelf())
if (intType.IsGenericType
&& intType.GetGenericTypeDefinition() == typeof(IDictionary<,>))
public static class ListExtensions
public static bool RemoveLast<T>(this IList<T> list, T item)
throw new ArgumentNullException();
var comparer = EqualityComparer<T>.Default;
for (int i = list.Count - 1; i >= 0; i--)
if (comparer.Equals(list[i], item))
public static void Test()
var settings = new JsonSerializerSettings
Converters = { new IgnoreCollectionTypeConverter() },
var movie = JsonConvert.DeserializeObject<Rootobject>(s, settings);
Console.WriteLine(JsonConvert.SerializeObject(movie, Formatting.Indented));
""$type"": ""ConsoleAppCompare.Movie, ConsoleAppCompare"",
""$type"": ""ConsoleAppCompare.Character[], ConsoleAppCompare"",
""$type"": ""ConsoleAppCompare.Character, ConsoleAppCompare"",
""Name"": ""Phil Coulson""
""$type"": ""ConsoleAppCompare.Character, ConsoleAppCompare"",
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: ");
public class AssertionFailedException : System.Exception
public AssertionFailedException() : base() { }
public AssertionFailedException(string s) : base(s) { }
public static class Assert
public static void IsTrue(bool value)
public static void IsTrue(bool value, string message)
throw new AssertionFailedException(message ?? "failed");