using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using Debug = System.Console;
public class ControlContractResolver : DefaultContractResolver
static readonly SerializationCallback callback = (o, context) =>
if (o is AddonUserControl auc)
Debug.WriteLine("AddonUserControl's OnDeserializedCallback called for {0}", auc);
auc.AddonUserControlOnDeserializedCalled = true;
protected override JsonContract CreateContract(Type objectType)
var contract = base.CreateContract(objectType);
if (typeof(AddonUserControl).IsAssignableFrom(objectType))
contract.OnDeserializedCallbacks.Add(callback);
public class AddonUserControl : BaseControl
public bool AddonUserControlOnDeserializedCalled { get; set; }
private void OnDeserializedMethod(StreamingContext context)
AddonUserControlOnDeserializedCalled = true;
static IContractResolver myResolver = new ControlContractResolver
public static void Test()
var control = new AddonUserControl();
var settings = new JsonSerializerSettings
ContractResolver = myResolver,
TypeNameHandling = TypeNameHandling.Auto,
var json = JsonConvert.SerializeObject(control, typeof(object), settings);
var control2 = JsonConvert.DeserializeObject<BaseControl>(json, settings);
Assert.AreEqual(control.GetType(), control2.GetType());
Assert.IsTrue(((AddonUserControl)control2).AddonUserControlOnDeserializedCalled);
public static void Main()
Console.WriteLine("Environment version: {0} ({1})", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , GetNetCoreVersion());
Console.WriteLine("{0} version: {1}", typeof(JsonSerializer).Assembly.GetName().Name, typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");
public static string GetNetCoreVersion()
var assembly = typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly;
var assemblyPath = assembly.CodeBase.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
int netCoreAppIndex = Array.IndexOf(assemblyPath, "Microsoft.NETCore.App");
if (netCoreAppIndex > 0 && netCoreAppIndex < assemblyPath.Length - 2)
return assemblyPath[netCoreAppIndex + 1];