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

调用JsonConvert.DeserializeObject()时对象丢失数据的问题排查

问题原因分析

这个问题的核心是Newtonsoft.Json在使用标记了[JsonConstructor]的构造函数反序列化时,没有正确将JSON属性绑定到构造函数的参数上,导致PartNumber属性没有被赋值。

具体来说:

  • 你的Part类属性的setter是private的,所以Newtonsoft.Json无法直接通过反射设置属性值,只能依赖你定义的带[JsonConstructor]的构造函数来初始化对象。
  • 虽然构造函数的参数名(如partNumber)和JSON的属性名(PartNumber)只是大小写差异,Newtonsoft.Json默认支持大小写不敏感匹配,但你同时使用了[DataMember]标记(这是给DataContractSerializer用的),这干扰了Newtonsoft.Json的默认匹配逻辑,导致参数partNumber没有正确获取到JSON中PartNumber的值。
解决方案

这里有几个可行的解决办法,你可以根据自己的代码设计选择:

方案1:给构造函数参数添加[JsonProperty]标记

明确指定每个构造函数参数对应的JSON属性名,消除匹配歧义:

[JsonConstructor]
public Part(
    [JsonProperty("WorkOrder")] string workOrder,
    [JsonProperty("PartNumber")] string partNumber,
    [JsonProperty("Revision")] string revision,
    [JsonProperty("PartName")] string partName,
    [JsonProperty("SerialNumber")] string serialNumber
) {
    WorkOrder = workOrder;
    PartNumber = partNumber;
    Revision = revision;
    PartName = partName;
    SerialNumber = serialNumber;
}

方案2:让Newtonsoft.Json识别[DataMember]标记

配置JsonSerializerSettings使用DataContractResolver,这样Newtonsoft.Json会遵循[DataMember]的标记来匹配属性:

Part p = JsonConvert.DeserializeObject<Part>(sqlcommand.ExecuteScalar().ToString(), new JsonSerializerSettings {
    ContractResolver = new DataContractResolver()
});

方案3:修改属性setter为public(如果设计允许)

如果不需要保持setter的私有性,直接把setter改成public,去掉[JsonConstructor],Newtonsoft.Json会直接设置属性值:

[DataMember]
public string PartNumber { get; set; }
[DataMember]
public string PartName { get; set; }
// 其他属性同理修改setter
验证

修改后重新运行代码,你会发现PartNumber属性能正确获取到JSON中的值,GetPartNumber()也会输出预期的20584。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 08:27:54