.NET对象列表JSON反序列化:解析Items内层节点且不改动Conditions属性
不修改Conditions类的前提下反序列化嵌套items的方案
可以实现,核心思路是先解析JSON提取目标嵌套节点,再单独反序列化,完全不需要改动原Conditions类的结构。
步骤说明
1. 定义嵌套结构对应的实体类
因为原Conditions类的Items是List<object>,无法直接映射嵌套的具体结构,所以单独定义需要的实体类(不影响原类):
// 对应外层items数组中的元素结构 public class InnerConditionItem { public List<SearchQueryItem> Items { get; set; } public object Id { get; set; } public object RecallQueryToken { get; set; } } // 对应内层items数组中的查询配置结构 public class SearchQueryItem { public Query Q { get; set; } public bool DWim { get; set; } public string QLang { get; set; } public bool ParseAlgorithm { get; set; } public bool SuggestCorrections { get; set; } public bool AutoCorrection { get; set; } public bool FuzzyMath { get; set; } public bool FuzzyMatch { get; set; } public bool IncludeFrenchUri { get; set; } public object TermUnitParse { get; set; } public string SuggestionCount { get; set; } public bool Synonyms { get; set; } public bool Equivs { get; set; } public bool Highlight { get; set; } public List<object> AnyAttr { get; set; } } // 对应q字段的结构 public class Query { public object Id { get; set; } public int Weight { get; set; } public string Name { get; set; } public bool OriginalSearch { get; set; } public string Value { get; set; } }
2. 解析JSON并提取目标节点(以Newtonsoft.Json为例)
先把整个JSON解析为可操作的动态对象,提取外层items数组第一个元素里的内部items集合:
using Newtonsoft.Json; using Newtonsoft.Json.Linq; // 注意:先修正原JSON的语法错误——把单引号改成双引号,补全外层{} string jsonStr = @" { ""items"": [ { ""items"": [ { ""q"": { ""id"": null, ""weight"": 0, ""name"": ""Original Search"", ""originalSearch"": true, ""value"": ""murder"" }, ""dWim"": true, ""qLang"": ""NaturalAnd"", ""parseAlgorithm"": false, ""suggestCorrections"": true, ""autoCorrection"": false, ""fuzzyMath"": false, ""fuzzyMatch"": false, ""includeFrenchUri"": false, ""termUnitParse"": null, ""suggestionCount"": ""1"", ""synonyms"": false, ""equivs"": true, ""highlight"": true, ""anyAttr"": [] } ], ""id"": null, ""recallQueryToken"": null } ], ""anyAttr"": [] }"; // 解析JSON为JObject var jsonObj = JObject.Parse(jsonStr); // 定位到目标嵌套items节点 var targetItemsToken = jsonObj["items"][0]["items"]; // 反序列化为具体的实体列表 var targetItems = targetItemsToken.ToObject<List<SearchQueryItem>>();
3. 关联到Conditions对象(可选)
如果需要把结果和原Conditions对象结合,直接修改Items集合的元素即可:
var conditions = JsonConvert.DeserializeObject<Conditions>(jsonStr); // 将原Items的第一个元素替换为反序列化后的具体集合 conditions.Items[0] = targetItems;
用System.Text.Json实现的方式
如果使用.NET内置的System.Text.Json,思路一致:
using System.Text.Json; using var doc = JsonDocument.Parse(jsonStr); var targetItemsElement = doc.RootElement.GetProperty("items")[0].GetProperty("items"); var targetItems = JsonSerializer.Deserialize<List<SearchQueryItem>>(targetItemsElement);
注意事项
- 原示例的JSON存在语法错误:JSON规范要求键和字符串值必须用双引号,且外层缺少包裹的
{},需要先修正才能正常解析。 - 所有操作都不会改动原Conditions类的属性结构,完全符合你的需求。
内容的提问来源于stack exchange,提问作者guiz
相关产品推荐
相关产品推荐

