使用Newtonsoft在C#中反序列化JSON至自定义类失败求助
我来帮你排查下把JSON反序列化到YoCurrency类失败的问题,大概率是踩了这几个常见的坑,咱们一步步来解决:
1. 先确认JSON结构是否和类匹配
很多时候反序列化失败是因为JSON的根结构和你的类不对应。比如如果你的JSON是对象数组([{}, {}]),或者外面套了一层父对象(比如{"data": {...}}),直接反序列化到YoCurrency肯定会报错。
举个例子,如果你的JSON是这种扁平结构,那和你的类是匹配的:
{ "Currency": "BTC", "high": 50000.0, "low": 48000.0, "avg": 49000.0, "vol": 1200.0, "vol_cur": 24.5, "last": 49500.0, "buy": 49400.0, "sell": 49600.0, "updated": 1620000000 }
但如果JSON是嵌套的,比如:
{ "success": true, "currency_data": { "Currency": "BTC", ... // 其他字段 } }
那你需要先定义一个根类来包裹YoCurrency:
public class RootResponse { public bool success { get; set; } public YoCurrency currency_data { get; set; } }
然后反序列化到RootResponse,再取里面的currency_data。
2. 检查属性大小写的匹配问题
默认的JSON序列化器(不管是Newtonsoft.Json还是System.Text.Json)大多是区分大小写的,你得确保类的属性名和JSON的键完全一致,或者通过特性/配置来忽略大小写:
如果你用Newtonsoft.Json(Json.NET)
你已经给vol_cur加了[JsonProperty("vol_cur")]特性,这没问题。如果其他JSON键是小写(比如high、low),那和你的类属性名一致,不需要额外配置;但如果JSON键是大写开头(比如High),你需要给对应属性也加上[JsonProperty]特性:
[JsonProperty("High")] public double high { get; set; }
如果你用System.Text.Json
默认是严格区分大小写的,你有两个解决办法:
- 给每个属性加
[JsonPropertyName]特性,比如:[JsonPropertyName("vol_cur")] public double vol_cur { get; set; } - 或者在反序列化的时候开启忽略大小写的选项:
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; var currency = JsonSerializer.Deserialize<YoCurrency>(jsonString, options);
3. 类的访问修饰符要注意
你定义的YoCurrency是默认的internal类,如果你的反序列化代码在不同的程序集里,会导致无法访问这个类。建议把类改成public:
public class YoCurrency { // 你的属性... }
4. 检查数据类型是否完全匹配
如果JSON里的字段类型和类里的不一致,也会反序列化失败:
- 比如JSON里的
updated是字符串(比如"1620000000"),但你的类里是int类型,这时候会报错; - 或者
high是字符串形式的数字(比如"50000"),但类里是double,也会解析失败。
这种情况要么修改类的属性类型为string,要么添加转换器来处理类型转换。比如用System.Text.Json的话,可以加一个数字转换器:
var options = new JsonSerializerOptions(); options.Converters.Add(new JsonNumberConverter()); var currency = JsonSerializer.Deserialize<YoCurrency>(jsonString, options);
5. 完整的反序列化示例代码
用Newtonsoft.Json的情况
先确保你已经安装了Newtonsoft.Json NuGet包,然后代码如下:
using Newtonsoft.Json; public class YoCurrency { public string Currency { get; set; } public double high { get; set; } public double low { get; set; } public double avg { get; set; } public double vol { get; set; } [JsonProperty("vol_cur")] public double vol_cur { get; set; } public double last { get; set; } public double buy { get; set; } public double sell { get; set; } public int updated { get; set; } } // 反序列化代码 string json = "你的完整JSON字符串"; YoCurrency currency = JsonConvert.DeserializeObject<YoCurrency>(json);
用System.Text.Json的情况
using System.Text.Json; public class YoCurrency { public string Currency { get; set; } public double high { get; set; } public double low { get; set; } public double avg { get; set; } public double vol { get; set; } [JsonPropertyName("vol_cur")] public double vol_cur { get; set; } public double last { get; set; } public double buy { get; set; } public double sell { get; set; } public int updated { get; set; } } // 反序列化代码 string json = "你的完整JSON字符串"; var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; YoCurrency currency = JsonSerializer.Deserialize<YoCurrency>(json, options);
如果按照上面的步骤还是解决不了,建议把完整的JSON数据和具体的错误信息贴出来,这样更容易精准定位问题~
内容的提问来源于stack exchange,提问作者Ilya

