为了账号安全,请及时绑定邮箱和手机立即绑定

反序列化泛型类型无法设置类型 T 的属性

反序列化泛型类型无法设置类型 T 的属性

C#
白衣非少年 2023-09-16 15:13:32
我在使用 Json.Net 将 JSON 字符串反序列化为通用类型时遇到一些问题。我遇到的问题是泛型类的属性正在正确反序列化,在这种情况下,SomeStrings下面的属性将按预期填充,但该Data属性被保留null。我希望有人能够阐明我所缺少的内容,因为序列化相同类型工作正常。请参阅下面的类结构:public class Foo{    public List<string> SomeStrings { get; protected set; } = new List<string>();    protected Foo()    {    }}public class GenericFoo<TBar> : Foo{    public TBar Data { get; private set; }    private GenericFoo() {}    public GenericFoo(TBar data)    {        Data = data;    }    public GenericFoo(TBar data, params string[] someStrings) :this(data)    {        SomeStrings = someStrings.ToList();    }}public class DataClass{    public int Id { get; set; }}我正在运行的代码:var settings = new JsonSerializerSettings(){    ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor};var response = new GenericFoo<DataClass>(new DataClass(){    Id = 10}, "Test");//serialises completely finevar json = JsonConvert.SerializeObject(response, settings); //Produces JSON: {"Data":{"Id":10},"SomeStrings":["Test"]}//all properties deserialised fine, Data left nullvar obj = JsonConvert.DeserializeObject<GenericFoo<DataClass>>(json, settings); 
查看完整描述

2 回答

?
眼眸繁星

TA贡献1873条经验 获得超9个赞

通过将[JsonConstructor]属性应用于构造函数

使用JsonConstructorAttribute指定在反序列化期间应使用构造函数来创建类。

public class GenericFoo<TBar> : Foo {

    public TBar Data { get; private set; }


    private GenericFoo() { }


    public GenericFoo(TBar data) {

        Data = data;

    }


    [JsonConstructor]

    public GenericFoo(TBar data, params string[] someStrings) : this(data) {

        SomeStrings = someStrings.ToList();

    }


}

反序列化时我得到了所需的行为。即使没有设置


public class Program

{

    public static void Main()

    {

        var response = new GenericFoo<DataClass>(new DataClass()

        {Id = 10}, "Test");

        //serialises completely fine

        var json = JsonConvert.SerializeObject(response);


        var obj = JsonConvert.DeserializeObject<GenericFoo<DataClass>>(json);

        Console.WriteLine(obj.Data.Id); // Prints 10

    }

}

.Net Fiddle 运行代码。


查看完整回答
反对 回复 2023-09-16
?
慕码人8056858

TA贡献1803条经验 获得超6个赞

要反序列化您的SomeString,只需使用JsonProperty ,如下所示:


 [JsonProperty]

 public List<string> SomeStrings { get; protected set; }

这不适用于具有私有 setter 的公共通用属性。但它适用于私有或受保护的通用属性。(也许是一个错误?)


 [JsonProperty]

 private TBar Data { get; set; }

这可以通过使用隐藏属性进行序列化来解决,如下所示:


[JsonIgnore]

public TBar Data { get; private set; }


[JsonProperty(PropertyName = nameof(Data))]

private TBar PrivateData

{

    get => Data;

    set => Data = value;

}


查看完整回答
反对 回复 2023-09-16
  • 2 回答
  • 0 关注
  • 92 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信