反序列化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
相关产品推荐
相关产品推荐

