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

时间:2019-08-22 11:13:47

标签: c# json.net

我在使用Json.Net将JSON字符串反序列化为通用类型时遇到了一些问题。

我正遇到的问题是正确地反序列化了通用类的属性,在这种情况下,下面的SomeStrings属性将按预期填充,但是Data属性保留为{ {1}}。

我希望有人可以阐明我所缺少的东西,因为序列化相同类型的工作正常。

请参见下面的类结构:

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; }
}

2 个答案:

答案 0 :(得分:1)

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

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

这不适用于带有私有设置程序的public通用属性。但是,它适用于私有或受保护的通用属性。 (也许是错误?)

 [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;
}

答案 1 :(得分:1)

通过将[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 of running code.