Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to have JSON.net honor the System.Text.Json JsonPropertyName attribute

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?

like image 386
Haacked Avatar asked Feb 05 '21 17:02

Haacked


People also ask

Which is better Newtonsoft JSON or System text JSON?

Json does case-insensitive property name matching by default. The System. Text. Json default is case-sensitive, which gives better performance since it's doing an exact match.

How do I get JSON net?

Right click the References node in your Project and click Manage Nuget Packages... In the Nuget Package Manager Dialog box, make sure Online is selected in the left pane. Type Json.Net in the search box in the top right. This will display the Json.Net Nuget Package in the search results pane in the middle.

How do I deserialize JSON?

A common way to deserialize JSON is to first create a class with properties and fields that represent one or more of the JSON properties. Then, to deserialize from a string or a file, call the JsonSerializer. Deserialize method.


1 Answers

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
like image 162
Guru Stron Avatar answered Nov 15 '22 00:11

Guru Stron