using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
public static void Main()
var parent = new Parent2()
new() { Foo = "foo1", Bar = "bar1" },
new() { Foo = "foo2", Bar = "bar2" }
var json1 = Newtonsoft.Json.JsonConvert.SerializeObject(parent, JsonSerializerSettingsWrite);
Console.WriteLine("Newtonsoft : Schema to JSON:");
Console.WriteLine(json1);
var schema1 = Newtonsoft.Json.JsonConvert.DeserializeObject<Parent2>(json1, JsonSerializerSettingsRead);
Console.WriteLine("Newtonsoft : JSON to Schema:");
Console.WriteLine(schema1);
var json2 = JsonSerializer.Serialize(parent, JsonSerializerOptionsWrite);
Console.WriteLine("Text.Json : Schema to JSON:");
Console.WriteLine(json2);
var schema2 = JsonSerializer.Deserialize<Parent2>(json2, JsonSerializerOptionsRead);
Console.WriteLine("Text.Json : JSON to Schema:");
Console.WriteLine(schema2);
json2 = JsonSerializer.Serialize(parent);
Console.WriteLine("Text.Json : Schema to JSON (no settings):");
Console.WriteLine(json2);
schema2 = JsonSerializer.Deserialize<Parent2>(json2);
Console.WriteLine("Text.Json : JSON to Schema (no settings):");
Console.WriteLine(schema2);
private static readonly Newtonsoft.Json.JsonSerializerSettings JsonSerializerSettingsRead = new Newtonsoft.Json.JsonSerializerSettings
ObjectCreationHandling = Newtonsoft.Json.ObjectCreationHandling.Reuse
private static readonly Newtonsoft.Json.JsonSerializerSettings JsonSerializerSettingsWrite = new Newtonsoft.Json.JsonSerializerSettings
Formatting = Newtonsoft.Json.Formatting.Indented,
StringEscapeHandling = Newtonsoft.Json.StringEscapeHandling.EscapeNonAscii,
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
ContractResolver = new ExcludeObsoletePropertiesResolver()
private static readonly JsonSerializerOptions JsonSerializerOptionsRead = new JsonSerializerOptions
PreferredObjectCreationHandling = JsonObjectCreationHandling.Populate,
ReadCommentHandling = JsonCommentHandling.Skip,
AllowTrailingCommas = true
private static readonly JsonSerializerOptions JsonSerializerOptionsWrite = new JsonSerializerOptions
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
TypeInfoResolver = new DefaultJsonTypeInfoResolver()
.WithAddedModifier(ExcludeObsoleteProperties)
private static void ExcludeObsoleteProperties(JsonTypeInfo typeInfo)
if (typeInfo.Kind != JsonTypeInfoKind.Object)
foreach (var property in typeInfo.Properties)
if (property.AttributeProvider?.IsDefined(typeof(ObsoleteAttribute), true) == true)
property.ShouldSerialize = (_, _) => false;
public Child1 Child { internal get; set; } = new();
public record Parent2 : Parent1
public Parent2(Parent1 parent) : base(parent) { }
public new Child2 Child { get; set; } = new();
public string CSV { internal get; set; } = "";
public record Child2 : Child1
public Child2(Child1 child) : base(child) { }
public List<Sub> List { get; set; } = [];
public class ExcludeObsoletePropertiesResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
protected override List<MemberInfo> GetSerializableMembers(Type objectType)
var memberList = base.GetSerializableMembers(objectType);
memberList.RemoveAll(item => item.IsDefined(typeof(ObsoleteAttribute), true));