VB.NET 中获取JObject内DB前缀键字段的实现方法
Newtonsoft.Json JObject 查找指定前缀键的正确实现
报错根因
你之前的写法触发错误,本质是两个层面的问题:
- JObject本身不会直接公开可被LINQ枚举的键集合,它的所有直接子属性需要通过实例方法
Properties()获取,直接对JObject对象本身调用Where自然找不到对应的扩展方法 - 即使拿到了属性集合,序列中的元素是
JProperty类型的节点对象,不是字符串,不能直接调用字符串的StartsWith方法,需要先取JProperty.Name属性拿到实际的键名字符串再做匹配
另外需要注意,你给出的示例JSON是多层嵌套结构:包含数组类型的data字段、嵌套对象类型的db003字段,仅查询当前层级的属性会遗漏嵌套结构里的目标键,必须通过递归遍历才能拿到全量匹配结果。
基础单层查询写法(仅查当前层级的直接子键)
如果只需要查当前JObject的第一层属性,直接修正查询逻辑即可,以你使用的VB语法为例:
' 匹配当前层级下所有键名以DB开头的属性,不区分大小写 Dim matchedProps = jObject _ .Properties() _ .Where(Function(prop) prop.Name.StartsWith("DB", StringComparison.OrdinalIgnoreCase))
全量递归查询写法(覆盖所有嵌套结构)
适配示例JSON的嵌套结构,需要编写递归遍历逻辑,覆盖对象、数组两类节点,确保不遗漏任何层级的目标键:
- 遇到JObject节点:遍历所有直接属性,匹配到符合规则的键就收集,再对属性的值做递归遍历
- 遇到JArray节点:遍历数组内的每个元素,逐个递归处理
- 遇到JValue叶子节点:无属性可匹配,直接跳过
对应的实现代码:
' 递归收集所有键名匹配指定前缀的JProperty节点 Iterator Function FindMatchedProperties(currentNode As JToken, keyPrefix As String) As IEnumerable(Of JProperty) ' 处理普通对象节点 If TypeOf currentNode Is JObject Then Dim currentObj = CType(currentNode, JObject) For Each prop In currentObj.Properties() ' 按前缀匹配键名,忽略大小写差异 If prop.Name.StartsWith(keyPrefix, StringComparison.OrdinalIgnoreCase) Then Yield prop End If ' 递归遍历属性值的子节点 For Each childProp In FindMatchedProperties(prop.Value, keyPrefix) Yield childProp Next Next End If ' 处理数组节点 If TypeOf currentNode Is JArray Then Dim currentArr = CType(currentNode, JArray) For Each arrItem In currentArr.Children() For Each childProp In FindMatchedProperties(arrItem, keyPrefix) Yield childProp Next Next End If End Function
调用方式:
' 从根节点JObject开始,查找所有以DB为前缀的键 Dim allDbRelatedFields = FindMatchedProperties(jObject, "DB").ToList()
常见注意事项
- 拿到匹配的
JProperty对象后,可以直接修改其Value属性完成字段调整,不需要重新定位节点位置,避免二次遍历的性能损耗 - 键名匹配时建议显式指定字符串比较规则,避免不同系统区域设置下出现匹配偏差
- 不需要将JObject转成字典做查询,这种方式会丢失原JToken的节点引用,后续修改值时反而需要额外的定位逻辑
内容的提问来源于stack exchange,提问作者C. de O.S.
相关产品推荐
相关产品推荐

