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

Newtonsoft.Json反序列化JSON列表返回数与属性数一致异常问题

问题描述

现有如下结构的JSON数据:

[{"query":[{"number":"0000-2022-64129734 / 19:26"},{"location":"xx"},{"date":"01.06.2022"},{"querytype":"uu"},{"reason":"TEST"},{"identitytype":"xx"}]},{"identity":[{"name":"xx"},{"surname":"xx"},{"id":"xx"},{"mothername":"xx"},{"fathername":"xx"},{"birthlocation":"xx"},{"birthday":"05"},{"birthmonth":"05"},{"birthyear":"1964"},{"birthlocationCity":"xx"}]},{"criminal_record_list":[[{"crime":"xx"},{"value":3}]]}]

当前定义的C#反序列化实体类及调用代码如下:

[JsonObject]
public class CrimeResultModel
{
    [JsonProperty("criminal_record_list")]
    public List<List<criminal_record_list>> criminal_record_list{ get; set; }

    [JsonProperty("query")]
    public List<query> query{ get; set; }

    [JsonProperty("identity")]
    public List<identity> identity{ get; set; }
    public long CriminalRecordType { get; set; }
}

public class criminal_record_list
{
    [JsonProperty("crime")]
    public string crime{ get; set; }

    [JsonProperty("value")]
    public int value{ get; set; }
}

public class query
{
    public string number{ get; set; }
    public string location{ get; set; }
    public string date{ get; set; }
    public string querytype{ get; set; }
    public string reason{ get; set; }
    public string identitytype{ get; set; }
}

public class identity
{
    public string name{ get; set; }
    public string surname{ get; set; }
    public string id{ get; set; }
    public string mothername{ get; set; }
    public string fathername{ get; set; }
    public string birthlocation{ get; set; }
    public string birthday{ get; set; }
    public string birthmonth{ get; set; }
    public string birthyear{ get; set; }
    public string birthlocationCity{ get; set; }
}
}

var result = Newtonsoft.Json.JsonConvert.DeserializeObject<List<CrimeResultModel>>(jsonString);

执行上述反序列化代码时,返回的列表长度与CrimeResultModel类的属性数量一致,各属性对应的子列表长度也与对应实体类的属性数量相等,反序列化结果不符合预期。反序列化异常结果参考截图:
反序列化结果截图

问题原因
  • 根结构映射逻辑错误:当前JSON根节点是数组,但数组内的3个元素分别是仅包含query、identity、criminal_record_list单个属性的零散对象,不是3个完整的CrimeResultModel实例。直接反序列化为List<CrimeResultModel>时,Json.NET会为数组每个元素生成一个独立的CrimeResultModel对象,仅填充元素中存在的单个属性,其余属性为null,最终返回的列表长度为3,恰好和CrimeResultModel的公开属性数量一致。
  • 子对象结构映射逻辑错误:JSON中query、identity对应的数组,内部元素也是一个个独立的单键值对对象(例如{"number":"xxx"}、{"location":"xx"}),不是一个包含所有字段的完整对象。当前定义的query、identity类将所有字段作为类的直接属性,反序列化时每个单键值对对象会生成一个对应的实体实例,仅填充匹配的单个字段,因此子列表长度和对应实体类的属性数量相等。
  • 代码存在语法错误:identity类定义末尾多写了一个闭合大括号},会直接导致编译失败。
解决方案

根据是否可以调整JSON结构,选择对应方案:

方案1:可修改JSON结构(推荐)

调整JSON结构,将根数组改为单个完整对象,同时把query、identity数组内分散的单属性对象合并为单个完整对象,调整后的JSON示例:

{
  "query": {
    "number": "0000-2022-64129734 / 19:26",
    "location": "xx",
    "date": "01.06.2022",
    "querytype": "uu",
    "reason": "TEST",
    "identitytype": "xx"
  },
  "identity": {
    "name": "xx",
    "surname": "xx",
    "id": "xx",
    "mothername": "xx",
    "fathername": "xx",
    "birthlocation": "xx",
    "birthday": "05",
    "birthmonth": "05",
    "birthyear": "1964",
    "birthlocationCity": "xx"
  },
  "criminal_record_list": [
    [
      {"crime":"xx","value":3}
    ]
  ],
  "CriminalRecordType": 0
}

同步调整实体类定义,修正语法错误,将query、identity属性的类型从列表改为对应实体类型,符合C#命名规范的实体代码如下:

[JsonObject]
public class CrimeResultModel
{
    [JsonProperty("criminal_record_list")]
    public List<List<CriminalRecordItem>> CriminalRecordList{ get; set; }

    [JsonProperty("query")]
    public QueryInfo Query{ get; set; }

    [JsonProperty("identity")]
    public IdentityInfo Identity{ get; set; }
    public long CriminalRecordType { get; set; }
}

public class CriminalRecordItem
{
    [JsonProperty("crime")]
    public string Crime{ get; set; }

    [JsonProperty("value")]
    public int Value{ get; set; }
}

public class QueryInfo
{
    public string number{ get; set; }
    public string location{ get; set; }
    public string date{ get; set; }
    public string querytype{ get; set; }
    public string reason{ get; set; }
    public string identitytype{ get; set; }
}

public class IdentityInfo
{
    public string name{ get; set; }
    public string surname{ get; set; }
    public string id{ get; set; }
    public string mothername{ get; set; }
    public string fathername{ get; set; }
    public string birthlocation{ get; set; }
    public string birthday{ get; set; }
    public string birthmonth{ get; set; }
    public string birthyear{ get; set; }
    public string birthlocationCity{ get; set; }
}

调整反序列化调用代码,直接反序列化为单个CrimeResultModel实例即可:

var result = Newtonsoft.Json.JsonConvert.DeserializeObject<CrimeResultModel>(jsonString);

方案2:不可修改JSON结构

如果无法调整上游返回的JSON格式,需要自定义JsonConverter,在反序列化时先将根数组中分散的三个对象合并为一个完整的CrimeResultModel实例,再遍历query、identity数组内的单属性对象,将属性值逐一赋值到对应的实体实例上,最终返回正确的映射结果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 23:54:32