using System.Collections;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using Microsoft.Extensions.Configuration;
[System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public sealed class JsonConfiguredPropertyNameAttribute : System.Attribute
public string Key { get; }
public JsonConfiguredPropertyNameAttribute(string key) => this.Key = key;
public class PropertyNamesFromConfigurationContractResolver : DefaultContractResolver
readonly IConfiguration config;
public PropertyNamesFromConfigurationContractResolver(IConfiguration config) => this.config = config ?? throw new ArgumentNullException(nameof(config));
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
var property = base.CreateProperty(member, memberSerialization);
if (member.GetCustomAttribute<JsonConfiguredPropertyNameAttribute>()?.Key is {} key)
property.PropertyName = config[key] ?? property.PropertyName;
public Project(string projectName) => this.ProjectName = projectName;
public string ProjectId { get; set; }
[JsonConfiguredPropertyName("fieldConfig:projectNameField")]
public string ProjectName { get; set; }
[JsonConfiguredPropertyName("fieldConfig:projectDescriptionField")]
public string ProjectDescription { get; set; }
[JsonConfiguredPropertyName("fieldConfig:projectCreatorField")]
public string ProjectCreator { get; set; }
public static void Test(IConfiguration config)
var inputJson = GetRequiredJson();
var settings = new JsonSerializerSettings();
settings.ContractResolver = new PropertyNamesFromConfigurationContractResolver(config)
NamingStrategy = new CamelCaseNamingStrategy(),
settings.NullValueHandling = NullValueHandling.Ignore;
var project = JsonConvert.DeserializeObject<Project>(inputJson, settings);
var outputJson = JsonConvert.SerializeObject(project, Formatting.Indented, settings);
Console.WriteLine(outputJson);
Assert.That(JToken.DeepEquals(JToken.Parse(inputJson), JToken.Parse(outputJson)));
static string GetRequiredJson() =>
"fieldA_0002": "description",
static string GetJson() =>
"projectNameField": "fieldA_0001",
"projectDescriptionField": "fieldA_0002",
"projectCreatorField": "fieldA_0003"
public static void Main(string[] args)
Console.WriteLine("Environment version: {0} ({1}), {2}", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , Environment.Version, Environment.OSVersion);
Console.WriteLine("System.Text.Json version: " + typeof(JsonSerializer).Assembly.FullName);
File.WriteAllText("appsettings.json", GetJson());
IConfiguration config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
Console.WriteLine("Failed with unhandled exception: ");
File.Delete("appsettings.json");