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

我在使用 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 fine

var json = JsonConvert.SerializeObject(response, settings); 


//Produces JSON: {"Data":{"Id":10},"SomeStrings":["Test"]}


//all properties deserialised fine, Data left null

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


白衣非少年
浏览 93回答 2
2回答

眼眸繁星

通过将[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 运行代码。

慕码人8056858

要反序列化您的SomeString,只需使用JsonProperty ,如下所示:&nbsp;[JsonProperty]&nbsp;public List<string> SomeStrings { get; protected set; }这不适用于具有私有 setter 的公共通用属性。但它适用于私有或受保护的通用属性。(也许是一个错误?)&nbsp;[JsonProperty]&nbsp;private TBar Data { get; set; }这可以通过使用隐藏属性进行序列化来解决,如下所示:[JsonIgnore]public TBar Data { get; private set; }[JsonProperty(PropertyName = nameof(Data))]private TBar PrivateData{&nbsp; &nbsp; get => Data;&nbsp; &nbsp; set => Data = value;}
打开App,查看更多内容
随时随地看视频慕课网APP