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

反序列化JSON时处理依赖其他属性的类属性空引用问题求助

问题描述

我有一个结构如下的类:

public class TestClass1 
{ 
    public TestClass1() 
    {
    }

    private string _name;

    public string ScriptName { get; set; }

    public string Name {
        get
        {
            return _name;
        }
        set
        {
            _name = value;
            ScriptName = a_baseProp1.Substring(0,4);
        }
    }

    public string a_baseProp1 { get; set; }
    public string a_baseProp2 { get; set; }
}

当使用Newtonsoft反序列化以下JSON时:

{ "Name": "abcdefgh", "a_baseProp1": "a_baseProp1", "a_baseProp2": "a_baseProp2" }

执行代码:

TestClass1 tc1 = (TestClass1)serializer.Deserialize(new JTokenReader(jObj), typeof(TestClass1));

触发了如下错误:

System.NullReferenceException: 'Object reference not set to an instance of an object.' TestClass1.a_baseProp1.get returned null.

我无法理解为何设置ScriptName时a_baseProp1为null。我尝试使用JsonProperty Order特性,期望处理Name属性时其他属性已完成赋值,但未生效。由于该类的属性setter和getter被其他项目使用,我无法修改它们。请问是否有可行的解决办法?

对重复问题提议的回应

本问题关注的是反序列化过程中读取已反序列化的对象属性值,而被提议的重复问题未涉及该场景。


解决办法

方法1:自定义JsonConverter控制赋值顺序

通过自定义转换器,先把所有属性值读取到临时结构,再按依赖顺序给TestClass1赋值,避免Name的setter提前触发空引用错误:

public class TestClass1Converter : JsonConverter<TestClass1>
{
    public override TestClass1 ReadJson(JsonReader reader, Type objectType, TestClass1 existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var jObj = JObject.Load(reader);
        var result = new TestClass1();
        
        // 先赋值依赖属性,再赋值Name
        result.a_baseProp1 = jObj["a_baseProp1"]?.Value<string>();
        result.a_baseProp2 = jObj["a_baseProp2"]?.Value<string>();
        result.Name = jObj["Name"]?.Value<string>();
        
        return result;
    }

    public override void WriteJson(JsonWriter writer, TestClass1 value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }
}

使用时注册转换器即可:

var serializer = new JsonSerializer();
serializer.Converters.Add(new TestClass1Converter());
TestClass1 tc1 = serializer.Deserialize<TestClass1>(new JTokenReader(jObj));

方法2:手动按顺序赋值

如果不想编写转换器,可先将JSON反序列化为JObject,再手动按依赖顺序给类属性赋值:

// 假设jObj是已加载的JSON对象
var tc1 = new TestClass1();

// 先赋值a_baseProp1、a_baseProp2
tc1.a_baseProp1 = jObj["a_baseProp1"].Value<string>();
tc1.a_baseProp2 = jObj["a_baseProp2"].Value<string>();
// 最后赋值Name,此时a_baseProp1已初始化
tc1.Name = jObj["Name"].Value<string>();

补充:JsonProperty.Order失效原因

Newtonsoft的JsonProperty.Order特性仅在JSON本身无明确顺序时生效。如果JSON中属性有明确顺序(比如你的JSON里Name排在a_baseProp1前面),框架会优先遵循JSON的属性顺序反序列化,忽略Order设置,这就是你的尝试未生效的原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 16:28:33