You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Json.Net反序列化时带参构造函数引发异常行为问题

问题原因与解决方案

原因分析

当Inner类使用带参的[JsonConstructor]时,Json.NET的反序列化逻辑会优先通过构造函数实例化对象:

  1. Json.NET先根据JSON字段匹配构造函数参数,创建Inner实例,此时Inner的Value属性会通过类内初始值声明生成一个Value对象(对应输出里的第二个Value constructor)。
  2. 针对JSON中的Value字段,Json.NET会尝试新建一个Value实例(对应输出里的第一个Value constructor),但由于Inner的Value属性是只读(仅含getter),Json.NET无法将新创建的Value实例赋值给该属性。
  3. 最终outer.Inner.Value保留的是初始生成的Value对象,其num字段为默认值0,而非JSON中的1。

而当Inner使用无参构造函数时,Json.NET会采用「先实例化、再逐个填充属性」的逻辑:直接复用Inner实例中已初始化的Value对象,将JSON中的num值填充进去,结果符合预期。

解决方案

以下是几种可行的解决方式,可根据类设计需求选择:

方案1:给Value属性添加[JsonProperty]标记

即使Value是只读属性,添加[JsonProperty]后,Json.NET会识别到需要对已存在的实例进行填充,而非创建新实例:

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

    public string Random { get; }

    [JsonProperty] // 添加该标记
    public Value Value { get; } = new();
}

修改后执行输出:

Value constructor
Inner JSON constructor
1

方案2:在构造函数中添加Value参数

调整Inner的带参构造函数,加入Value类型的参数,让Json.NET在构造Inner时直接传入反序列化后的Value对象:

public class Inner
{
    [JsonConstructor]
    protected Inner(string random, Value value)
    {
        Console.WriteLine("Inner JSON constructor");
        Random = random;
        // 处理JSON未传入Value的情况,避免null
        Value = value ?? new Value();
    }

    public string Random { get; }

    public Value Value { get; }
}

这种方式下,Json.NET会直接将JSON中的Value数据反序列化为实例传入构造函数,最终num值会正确设置为1。

方案3:保留无参构造函数(若允许类设计变更)

如果业务允许Inner存在无参构造函数,Json.NET会自动采用属性填充逻辑,无需额外修改即可得到预期结果:

public class Inner
{
    // 保留无参构造函数
    public Inner() {}

    [JsonConstructor] // 可选,若需优先使用带参构造可保留,但需结合方案1或2
    protected Inner(string random)
    {
        Console.WriteLine("Inner JSON constructor");
        Random = random;
    }

    public string Random { get; }

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

内容的提问来源于stack exchange,提问作者stripies

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 13:36:10