Newtonsoft.Json中JArray.ToObject反序列化时name字段为null问题
JArray.ToObject反序列化时name字段未赋值的原因及修复
以下按问题出现概率从高到低排序:
1. 属性访问器/特性标记配置错误
这是90%同类问题的诱因:
- 检查
Root类中name对应属性的定义:必须是public修饰的可读可写属性,如果是私有属性、类字段、只有get没有set的只读属性,都无法被赋值 - 如果属性用了C# 9.0+的
init访问器,且你使用的Newtonsoft.Json版本低于13.0.1,序列化器无法识别init访问器,会直接跳过赋值,表现为属性取默认值(字符串为null/空),升级Newtonsoft.Json到最新稳定版,或把init改成set即可修复 - 检查属性上是否误加了
[JsonIgnore]特性,或[JsonProperty("错误字段名")]标记,如果加了JsonProperty特性,显式指定参数为"name"即可强制匹配 - 如果
Root类定义了带参数的自定义构造函数,检查构造函数参数列表中是否存在name匹配的参数,且构造函数逻辑中正确给Name属性赋值;JSON.NET反序列化时会优先调用参数匹配最多的构造函数,参数名不匹配时不会给对应属性赋值
2. 自定义序列化配置干扰映射
如果调用ToObject方法时传入了自定义JsonSerializerSettings:
- 检查是否配置了自定义
ContractResolver,比如设置了DefaultContractResolver.NamingStrategy和返回字段名冲突,或配置了属性过滤规则把name属性排除 - 检查是否配置了
Error事件委托吞掉了反序列化异常:如果name字段实际返回值类型和你定义的属性类型不匹配(比如你把name定义成了枚举、数值类型),异常被吞掉后属性会保持默认空值,而code字段类型匹配所以正常赋值
可以临时调用无参数的ToObject<List<Root>>()使用默认配置测试,如果默认配置下name能正常赋值,即可定位为自定义配置的问题。
3. 快速排查方法
直接取JArray中的第一条JObject做单步测试:
JToken firstItem = jArray[0]; // 调试时查看这个值是否为"Bitcoin" var rawName = firstItem["name"]?.ToString(); // 单条映射测试 var testObj = firstItem.ToObject<Root>();
如果rawName能取到正确值但testObj.Name为空,100%是上面提到的实体类定义或序列化配置问题,和接口返回、JArray解析逻辑无关。
可直接使用的正确实体类定义参考
public class Links { [JsonProperty("website")] public string Website { get; set; } [JsonProperty("twitter")] public string Twitter { get; set; } // 其他links字段按接口返回结构补充即可 } public class Root { [JsonProperty("name")] public string Name { get; set; } [JsonProperty("code")] public string Code { get; set; } [JsonProperty("symbol")] public string Symbol { get; set; } [JsonProperty("rank")] public int Rank { get; set; } [JsonProperty("links")] public Links Links { get; set; } }
显式添加
[JsonProperty]标记可以完全规避大小写、命名策略不匹配导致的映射失败问题,是稳定性最高的写法。
内容的提问来源于stack exchange,提问作者HaxionAlpha
相关产品推荐
相关产品推荐

