VB.Net使用Newtonsoft解析JSON遇StartArray错误求助
VB中Newtonsoft解析JSON数组报错的解决思路
问题背景
我用VB开发,使用Newtonsoft解析一段已通过JSONLINT验证的合法JSON时失败,报错信息如下:
Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 1, position 1.
目标JSON内容:
[{ "payload": { "MainBlock": { "S0": { "interfaceId": "IF-XXX", "schemaVersion": "1.1.1", "eventCode": "[ABCPeriodData]" }, "S1": { "environment": "DEV", "senderUniqueReference": "S-005-1234567abc-SUP-20222313-12345687A", "sentTimestamp": "2022-12-31T12:35:45\u002B06:30", "senderId": "4ce0a6cd4b", "senderRole": "ABC", "DIPConnectionProviderId": "1009012345" }, "A0": { "always": ["SUP", "SDS", "ADS", "UMDS"] }, "D0": { "transactionId": "T-022-4ce0a6cd4b-ABC-20230503-000404", "transactionTimestamp": "2023-05-03T13:34:34\u002B00:00", "publicationId": "PUB-XXX" } }, "SecondBlock": { "B903List": [{ "calculationDay": { "calculationDayDate": "2022-12-31T12:35:45\u002B06:30", "calculationPeriodDuration": 30 }, "XYZcalculationPeriods": [{ "XYZroup": { "GSPGroupID": "_K", "connectionTypeIndicator": "W", "domesticPremiseIndicator": true, "marketSegmentIndicator": "A", "measurementQuantityID": "AI" }, "XYZroupcalculationPeriods": [{ "calculationPeriodEffectiveToDateTime": "2022-12-31T12:35:45\u002B06:30", "loadShapePeriodValue": "123456789.123", "defaultLoadShapeFlag": "A" }, { "calculationPeriodEffectiveToDateTime": "2022-12-31T12:35:45\u002B06:30", "loadShapePeriodValue": "123456789.123", "defaultLoadShapeFlag": "A" }] }] }] } } }]
我之前用JObject.Parse()解析其他JSON文件正常,但这段JSON以数组开头,用同样方法就报错,尝试以下代码仍未解决:
Dim o As JObject = JObject.Parse(Json) Dim results As List(Of JToken) = o.Children().ToList For Each item As JProperty In results item.CreateReader() If item.Value.Type = JTokenType.Array Then Dim results2 As List(Of JToken) = item.Value.ToList For Each subitem As JObject In results2 WorkingDictionary = New Dictionary(Of String, String) Dim results3 As List(Of JToken) = subitem.Children().ToList For Each temp2 As JProperty In results3 temp2.CreateReader() Try Debug.Print(temp2.Name) WorkingDictionary.Add(temp2.Name, temp2.Value.ToString) Catch ex As Exception Debug.Print(ex.StackTrace) Debug.Print(ex.Message) End Try Next RetVal.Add(WorkingDictionary) Next Else Debug.Print(item.Name.ToString + " " + item.Value.ToString) End If Next
解决方案
核心问题原因
你的JSON最外层是数组(以[开头),但你使用了仅能解析单个JSON对象(以{开头)的JObject.Parse()方法,因此触发"StartArray"类型不匹配错误。
修正后的解析代码
改用JArray.Parse()解析外层数组,再逐层遍历嵌套结构:
Try ' 解析最外层数组 Dim arr As JArray = JArray.Parse(Json) ' 遍历数组中的每个对象(此示例数组仅含一个元素) For Each obj As JObject In arr ' 获取payload对象 Dim payload As JObject = obj("payload") ' 处理MainBlock下的数据 Dim mainBlock As JObject = payload("MainBlock") Debug.Print("interfaceId: " & mainBlock("S0")("interfaceId").ToString()) Debug.Print("senderUniqueReference: " & mainBlock("S1")("senderUniqueReference").ToString()) ' 处理SecondBlock下的数据 Dim secondBlock As JObject = payload("SecondBlock") Dim b903List As JArray = secondBlock("B903List") For Each b903Item As JObject In b903List Dim calculationDay As JObject = b903Item("calculationDay") Debug.Print("calculationPeriodDuration: " & calculationDay("calculationPeriodDuration").ToString()) Dim xyzPeriods As JArray = b903Item("XYZcalculationPeriods") For Each xyzItem As JObject In xyzPeriods Dim xyzGroup As JObject = xyzItem("XYZroup") Debug.Print("GSPGroupID: " & xyzGroup("GSPGroupID").ToString()) Dim xyzCalcPeriods As JArray = xyzItem("XYZroupcalculationPeriods") For Each periodItem As JObject In xyzCalcPeriods Debug.Print("loadShapePeriodValue: " & periodItem("loadShapePeriodValue").ToString()) Next Next Next Next Catch ex As Exception Debug.Print(ex.StackTrace) Debug.Print(ex.Message) End Try
字典收集版代码(适配你的原有需求)
如果仍需要将数据收集到字典中,调整后的代码如下:
Try Dim arr As JArray = JArray.Parse(Json) For Each obj As JObject In arr Dim payload As JObject = obj("payload") ' 遍历payload下的所有顶级块 For Each prop As JProperty In payload.Properties() WorkingDictionary = New Dictionary(Of String, String) WorkingDictionary.Add(prop.Name, prop.Value.ToString()) RetVal.Add(WorkingDictionary) Next Next Catch ex As Exception Debug.Print(ex.StackTrace) Debug.Print(ex.Message) End Try
关键要点总结
- 区分JSON最外层结构:对象用
JObject.Parse(),数组用JArray.Parse() - 解析嵌套结构时,通过
JToken("键名")逐层获取值,注意判断目标节点是对象还是数组 - 遍历对象的所有属性时,使用
Properties()方法获取键值对集合
内容的提问来源于stack exchange,提问作者Tym
相关产品推荐
相关产品推荐

