Как выполнить цикл для динамических объектов JObject в другом JObject?
На самом деле я обрабатываю некоторые данные JSON, полученные из некоторого API в старом проекте VB.NET в Framework 3.5.
Я застрял в обработке следующего ответа:
{
"data": {
"89359": {
"name": "A",
//...
},
"89360": {
"name": "B",
//...
}
}
}
Каждый элемент данных является динамическим, но API не устанавливает данные как массив, я пытался получить данные из каждого элемента, как я еще делал для массивов JSON, например:
Dim options As JObject = JObject.Parse(json)
For Each opt As JObject In options("data")
MsgBox(opt("name"))
Next
Но в этом случае это не работает, поскольку, как я уже сказал, данные не являются массивом...
Так как же обрабатывать данные из этого JSON, поскольку 89359 и 89360 являются динамическими?
2 ответа
Ваша проблема в том, что
options("data")
будет объявлена, чтобы иметь тип JToken
будучи на самом деле типа JObject
, поэтому, когда вы его перечисляете, вы фактически перечисляете его JProperty
дети. Но вам нужны ценности тех
JProperty
объекты, которые находятся на один уровень ниже в иерархии:
For Each jProperty As JProperty In options("data")
Dim propertyName = jProperty.Name ' The "89359" names, in case you need them for some reason
Dim opt As JObject = jProperty.Value
Dim name As String = opt("name") ' Cast the name to a String using the JToken implicit casting operator
' Use the name as required
MsgBox(name)
Next
Демо скрипка здесь.
Предполагая, что объект, имеющий свойство name, имеет другие свойства, я бы сделал следующее:
- Создайте класс для представления объекта со свойством name
- Десериализовать входящие данные в JObject
- Получить элемент данных JObject
- Вызов ToObject с шага 3 в словарь (Of Integer, DataObject)
Вот пример:
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Module Module1
Sub Main()
Dim input As String = "{""data"": {""89359"": {""name"": ""A"" }, ""89360"": {""name"": ""B"" } } }"
Dim data = JsonConvert.DeserializeObject(Of JObject)(input)
Dim dataItems = data.Item("data").ToObject(Of Dictionary(Of Integer, DataObject))
For Each dataItem In dataItems
Console.WriteLine("Key: {0}, DataObject.Name: {1}", dataItem.Key, dataItem.Value.name)
Next
Console.ReadLine()
End Sub
End Module
Public Class DataObject
Public Property name As String
' ...
End Class
Теперь объекты существуют как массив через
dataItems.Values
метод.
Живой пример: скрипка