简体   繁体   中英

What is the equivalent of Newtonsoft.Json's / Json.Net's JsonProperty field in System.Text.Json?

I wanted to know what the euqivalent of the Newtonsoft.Json's / Json.Net's JsonProperty field in System.Text.Json is.

Example:

using Newtonsoft.Json;

public class Example
{
    [JsonProperty("test2")]
    public string Test { get; set; }
}

References:

Just in case, anyone else falls over this. The property is renamed to JsonPropertyName and comes from System.Text.Json.Serialization in the System.Text.Json nuget package.

Example:

using System.Text.Json.Serialization;

public class Example
{
    [JsonPropertyName("test2")]
    public string Test { get; set; }
}

References:

Note for anyone who finds this looking to replace Newtonsoft with System.Text.Json specifically getting a private property to serialize. Newtonsoft will happily serialize a private property with the Newtonsoft.Json.JsonProperty attribute, but putting System.Text.Json.Serialization.JsonPropertyName on a private property doesn't work. For example:

enum Animal { Cat, Dog }
class Foo
{
    [Newtonsoft.Json.JsonProperty("animals")]
    [System.Text.Json.Serialization.JsonPropertyName("animals")]
    private string AnimalForSerializer
    {
        get => AnimalForMe.ToString() + "s";
        set => AnimalForMe = Enum.Parse<Animal>(value.TrimEnd('s'));
    }
 
    [System.Text.Json.Serialization.JsonIgnore]
    [Newtonsoft.Json.JsonIgnore]
    public Animal AnimalForMe { get; set; }
}

var b = new Foo { AnimalForMe = Animal.Dog };

var json = System.Text.Json.JsonSerializer.Serialize(b);
var fromJson = System.Text.Json.JsonSerializer.Deserialize<Foo>(json);
Console.WriteLine($"{json} -> {fromJson.AnimalForMe}");

json = Newtonsoft.Json.JsonConvert.SerializeObject(b);
fromJson = Newtonsoft.Json.JsonConvert.DeserializeObject<Foo>(json);
Console.WriteLine($"{json} -> {fromJson.AnimalForMe}");

Outputs

{} -> Cat
{"animals":"Dogs"} -> Dog

To replace this behavior you need JsonInclude . Or rather, to almost replace. The System.Text.Json team decided not to support private properties. If you try you will get an error like "The non-public property 'AnimalForSerializer' on type 'Foo' is annotated with 'JsonIncludeAttribute' which is invalid.". But you can have a private setter, apparently:


class Foo
{
    [Newtonsoft.Json.JsonProperty("animals")]
    [System.Text.Json.Serialization.JsonInclude]
    [System.Text.Json.Serialization.JsonPropertyName("animals")]
    public string AnimalForSerializer
    {
        get => AnimalForMe.ToString() + "s";
        private set => AnimalForMe = Enum.Parse<Animal>(value.TrimEnd('s'));
    }
    
    [System.Text.Json.Serialization.JsonIgnore]
    [Newtonsoft.Json.JsonIgnore]
    public Animal AnimalForMe { get; set; }
}

var b = new Foo { AnimalForMe = Animal.Dog };

var json = System.Text.Json.JsonSerializer.Serialize(b);
var fromJson = System.Text.Json.JsonSerializer.Deserialize<Foo>(json);
Console.WriteLine($"{json} -> {fromJson.AnimalForMe}");

json = Newtonsoft.Json.JsonConvert.SerializeObject(b);
fromJson = Newtonsoft.Json.JsonConvert.DeserializeObject<Foo>(json);
Console.WriteLine($"{json} -> {fromJson.AnimalForMe}");

Outputs

{"animals":"Dogs"} -> Dog
{"animals":"Dogs"} -> Dog

Of course, not having private breaks encapsulation, but what can you do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM