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 UpcastingContractResolver<TDerived, TBase> : DefaultContractResolver where TDerived: TBase
readonly HashSet<string> baseProperties = ((JsonObjectContract)JsonSerializer.Create().ContractResolver.ResolveContract(typeof(TBase)))
.Properties.Select(p => p.UnderlyingName)
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
var properties = base.CreateProperties(type, memberSerialization);
if (type == typeof(TDerived) || type.IsSubclassOf(typeof(TDerived)))
foreach (var property in properties)
if (!baseProperties.Contains(property.UnderlyingName))
[JsonObject(MemberSerialization.OptIn)]
public string Id { get; set; }
public string Title { get; set; }
[JsonObject(MemberSerialization.OptIn)]
public class Recipe : RecipeShort
private List<Ingredient> ingredients = new List<Ingredient>();
public string Method { get; set; }
public static void Test()
string str1 = Newtonsoft.Json.JsonConvert.SerializeObject(res);
Console.WriteLine("\nDefault serialization of {0}", res);
var settings = new JsonSerializerSettings
ContractResolver = new UpcastingContractResolver<Recipe, RecipeShort>(),
var str2 = Newtonsoft.Json.JsonConvert.SerializeObject(res, settings);
Console.WriteLine("\nSerialization of {0} using {1}", res, settings.ContractResolver);
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: ");