参数化构造函数在 Json.Net 中反序列化时导致意外行为

问题描述 投票:0回答:1
using System;
using System.IO;

using Newtonsoft.Json;

public class PopulateTest
{
    public static void Test()
    {
        JsonSerializer serializer = JsonSerializer.CreateDefault();
        string json = "{\"Inner\":{\"Random\":\"a\",\"Value\":{\"num\":1}}}";
        Outer outer = new();
        using (StringReader reader = new(json)) {
            serializer.Populate(reader, outer);
        }
        Console.Log(outer.Inner.Value.num);
    }
}

public class Outer
{
    public Outer() { }

    public Inner Inner { get; set; }
}

public class Inner
{
    public Inner(string random, int count)
    {
        Console.Log("Inner constructor");
        Random = random;
        Value.num = count;
    }

    [JsonConstructor]
    protected Inner(string random)
    {
        Console.Log("Inner JSON constructor");
        Random = random;
    }

    public string Random { get; }

    public Value Value { get; } = new();
}

public class Value
{
    public int num;

    public Value() => Console.Log("Value constructor");
}

这是我正在使用的代码示例。 JSON

{"Inner":{"Random":"a","Value":{"num":1}}}
产生以下输出:

Value constructor
Value constructor
Inner JSON constructor
0

第一个

Value constructor
是从 Json.Net 库的
Newtonsoft.Json.Serialization.JsonSerializerInternalReader:CreateNewObject
调用的,第二个
Value constructor
来自初始值。

预期的行为是填充

Value
而不是创建新对象,当然,反序列化后
outer.Inner.Value.num
1
。但是,当使用默认构造函数时(删除
string random
作为
Inner
JsonConstructor
的参数),它可以正常运行。其输出是:

Value constructor
Inner JSON constructor
1
c# json.net
1个回答
0
投票

您应该将属性 [JsonConstructor] 添加到与传递的 json 字符串匹配的构造函数,当前代码显示它正在使用随机变量调用构造函数并且设置正确,但其中的 value 和 num 不是。 像这样更改构造函数:


    [JsonConstructor]
    public Inner(string random, Value value)
    {
        Console.WriteLine("Inner constructor");
        Random = random;
        Value = value;
    }

    //[JsonConstructor]
    protected Inner(string random)
    {
        Console.WriteLine("Inner JSON constructor");
        Random = random;
    }

注意第一个构造函数的变化,接受值对象而不是计数。这样你的代码应该可以工作

© www.soinside.com 2019 - 2024. All rights reserved.