反序列化对象类型获取值抛出空引用

Deserialized object type get value throw null reference

提问人:Rouzbeh Zarandi 提问时间:2/11/2022 最后编辑:Rouzbeh Zarandi 更新时间:2/11/2022 访问量:515

问:

我有一个来自 AJAX 的 JSON 响应,我正在尝试将其反序列化为对象类型(不是定义的模型类)并访问其属性值。反序列化程序工作正常,但是当尝试获取该值时,我收到空引用错误。

// on break point i can clearly see the object properties and values and its not null
var tankJsonObj = JsonConvert.DeserializeObject<object>(tankJson);

//here from GetValue i get the null refernce error
var test = tankJsonObj.GetType().GetProperty("tankName").GetValue(tankJsonObj, null).ToString();

我尝试了测试数据

var tankJsonObj = new { tankName = "xx" };
var test = tankJsonObj.GetType().GetProperty("tankName").GetValue(tankJsonObj, null).ToString();

它工作正常。我不明白为什么由反序列化程序启动的对象不是 null 在获取属性值时抛出错误。

object value

C# 对象 NullReferenceException

评论

1赞 aybe 2/11/2022
原因很简单,没有属性。objecttankName
0赞 Rouzbeh Zarandi 2/11/2022
蔚来我有那个......问题现在通过图像进行编辑,以确保 tankName 存在
0赞 Rouzbeh Zarandi 2/11/2022
好的,现在我看到 {{ tankName=“” }} 而不是 { tankName = “” }

答:

1赞 Peter B 2/11/2022 #1

第一个参数需要是 tankJsonObj,因为将从该对象读取值。GetValue()

更改代码:

var tankJsonObj = new { tankName = "xx" };
var test = tankJsonObj.GetType().GetProperty("tankName").GetValue(tankJsonObj, null).ToString();
Console.WriteLine(test); // "xx"

工作演示:https://dotnetfiddle.net/tOtRUf


但是,当反序列化为 时,只有支持的属性才会被反序列化,并且有...没有!因此,JSON 中的所有属性都将被忽略。objectobject

一个简单的解决方法是改用目标类型(在命名空间中)。这有点像键和值的字典,并且会接受任何属性。生成的代码非常简单,甚至不需要反射:JObjectNewtonsoft.Json.Linq

var tankJsonObj = JsonConvert.DeserializeObject<JObject>("{ tankName: \"xx\" }");
var test = tankJsonObj.GetValue("tankName")?.ToString();
Console.WriteLine(test); // "xx"

评论

0赞 Rouzbeh Zarandi 2/11/2022
两种方式都有效......当然,对于未反序列化的测试一,我提到测试一有效,但不适用于反序列化测试。我再次检查了你的,但我仍然有同样的问题:(
0赞 Rouzbeh Zarandi 2/11/2022
我认为断点显示的问题是来自反序列化数据的 {{..... }}
1赞 Peter B 2/11/2022
请看我的更新。
2赞 Richard Deeming 2/11/2022 #2

JsonConvert.DeserializeObject<object>返回一个 JObject 实例。该类没有名为 的属性,因此返回 。tankNametankJsonObj.GetType().GetProperty("tankName")null

使用匿名类型进行测试时,该类型确实具有一个名为 的属性。tankName

您不需要反射即可从以下位置提取值:JObject

JObject tankJsonObj = JsonConvert.DeserializeObject<JObject>(tankJson);
string tankName = tankJsonObj["tankName"]?.ToString();