using System.Collections.Generic;
public static void Main()
var json = foo.SerializeOld();
var obj = json.Deserialize<Foo>();
foreach(IBar bar in obj.Bars)
Console.WriteLine(bar.GetValueAsString());
public static class SerializationExtensions
public static string SerializeOld<T>(this T source)
var json = ServiceStack.Text.JsonSerializer.SerializeToString(source, typeof(T));
public static string Serialize<T>(this T source)
var json = Newtonsoft.Json.JsonConvert.SerializeObject(source, new Newtonsoft.Json.JsonSerializerSettings {
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto
public static T Deserialize<T>(this string json)
json = json.AsNewtonsoftJsonCompatibleString();
T output = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(json, new Newtonsoft.Json.JsonSerializerSettings {
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto
private static string AsNewtonsoftJsonCompatibleString(this string json)
if (!IsValidJson(json)) throw new ArgumentException("Not a valid JSON");
json = json.Replace("__type", "$type");
private static bool IsValidJson(string strInput)
if (string.IsNullOrWhiteSpace(strInput)) { return false; }
strInput = strInput.Trim();
if ((strInput.StartsWith("{") && strInput.EndsWith("}")) ||
(strInput.StartsWith("[") && strInput.EndsWith("]")))
var obj = Newtonsoft.Json.Linq.JToken.Parse(strInput);
catch (Newtonsoft.Json.JsonReaderException)
public class PolymorphicTypeResolve : System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver
public override System.Text.Json.Serialization.Metadata.JsonTypeInfo GetTypeInfo(Type type, System.Text.Json.JsonSerializerOptions options)
System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo = base.GetTypeInfo(type, options);
Type basePointType = typeof(IBar);
if (jsonTypeInfo.Type == basePointType)
jsonTypeInfo.PolymorphismOptions = new System.Text.Json.Serialization.Metadata.JsonPolymorphismOptions
TypeDiscriminatorPropertyName = "$type",
IgnoreUnrecognizedTypeDiscriminators = true,
UnknownDerivedTypeHandling = System.Text.Json.Serialization.JsonUnknownDerivedTypeHandling.FailSerialization,
new System.Text.Json.Serialization.Metadata.JsonDerivedType(typeof(Bar1), $"{typeof(Bar1).Name}, {typeof(Bar1).Module}"),
new System.Text.Json.Serialization.Metadata.JsonDerivedType(typeof(Bar2), $"{typeof(Bar2).Name}, {typeof(Bar2).Module}")
public List<IBar> Bars { get; set; } = [];
public Foo(List<IBar> bars)
if (bars is null) return;
string GetValueAsString();
public int Value { get; set; }
public string GetValueAsString()
public string Value { get; set; }
Value = string.IsNullOrWhiteSpace(val)
public string GetValueAsString()