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 ConverterReplacingContractResolver : DefaultContractResolver
readonly Dictionary<(Type type, string name), JsonConverter?> replacements;
public ConverterReplacingContractResolver(IEnumerable<KeyValuePair<(Type type, string name), JsonConverter?>> replacements) =>
this.replacements = (replacements ?? throw new ArgumentNullException()).ToDictionary(r => r.Key, r => r.Value);
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
var property = base.CreateProperty(member, memberSerialization);
if (member.DeclaringType != null && replacements.TryGetValue((member.DeclaringType, member.Name), out var converter))
property.Converter = converter;
[JsonConverter(typeof(MyJsonConverter))]
public string Property { get; set; }
public class SubContract : Contract { }
public class MyJsonConverter : JsonConverter
private readonly string _parameter;
public MyJsonConverter() : this("") { }
public MyJsonConverter(string parameter) => this._parameter = parameter;
public override bool CanConvert(Type objectType) => objectType == typeof(string);
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) =>
_parameter + (string?)JToken.Load(reader);
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) =>
writer.WriteValue((string)value!);
public static void Test()
var originalContract = new SubContract { Property = "hello" };
var json = JsonConvert.SerializeObject(originalContract);
var _parameter = "my runtime parameter: ";
var replacementsConverters = new KeyValuePair<(Type type, string name), JsonConverter?> []
new((typeof(Contract), nameof(Contract.Property)), new MyJsonConverter(_parameter)),
var resolver = new ConverterReplacingContractResolver(replacementsConverters)
var settings = new JsonSerializerSettings
ContractResolver = resolver,
var contract = JsonConvert.DeserializeObject<SubContract>(json, settings);
Console.WriteLine("Round-tripped {0}:", contract);
Console.WriteLine(JsonConvert.SerializeObject(contract, settings));
Assert.AreEqual(_parameter + originalContract.Property, contract?.Property);
public static void Main()
Console.WriteLine("Environment version: {0} ({1}), {2}", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , Environment.Version, Environment.OSVersion);
Console.WriteLine("{0} version: {1}", typeof(JsonSerializer).Namespace, typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");