I have a C# type that represents a deserialized C# payload. But it's deserialized in one place by System.Text.Json. In another place, it's Json.NET.
So right now, I have to attribute the properties using both [JsonProperty]
(for Json.NET) and [JsonPropertyName]
(for System.Text.Json).
Is there a way to tell Json.NET recognize the JsonPropertyName attribute so I don't have to annotate each property twice?
You can create custom contract resolver which will search for JsonPropertyName
attribute and use value from it. Example one can look something like that:
public class ContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
if (member.GetCustomAttribute<JsonPropertyNameAttribute>() is {} stj)
{
property.PropertyName = stj.Name;
return property;
}
return property;
}
}
And usage:
class MyClass
{
[JsonProperty("P1")]
public int MyProperty { get; set; }
[JsonPropertyName("P2")]
public int MyProperty2 { get; set; }
}
var settings = new JsonSerializerSettings
{
ContractResolver = new ContractResolver()
};
Console.WriteLine(JsonConvert.SerializeObject(new MyClass(), settings)); // prints {"P1":0,"P2":0}
Console.WriteLine(JsonConvert.DeserializeObject<MyClass>("{'P1':1,'P2':2}", settings).MyProperty2); // prints 2