jameskm69 Ответов: 3

Vb.net десериализовать JSON с


Привет, у меня есть досье API2.txt которые содержат следующее:
{
    "results": [{
        "rating2": 6.66666,
        "downloads_min": 5000000,
        "klm": [{
            "top1": "mine"
        },
        {
            "top2": "yours"
        }]
    },
    {
        "rating2": 4.4444,
        "downloads_min": 505550000,
        "klm": [{
            "top1": "2mine"
        },
        {
            "top2": "2yours"
        }]
    },
    {
        "rating2": 900000,
        "downloads_min": 505550000,
        "klm": [{
            "top1": "mine"
        },
        {
            "top2": "yours"
        }]
    }],
    "number_results": 263,
    "has_next": true,
    "page": 1,
    "num_pages": 132,
    "limit": 2
}


Я могу получить значение любых ключей, кроме "top1" и "top2". как я могу получить значение для "top1" и "top2"? Я использую следующий код для извлечения:

Что я уже пробовал:

Dim value As String = File.ReadAllText("C:\Farmers\API\API2.txt")
Dim json As JObject = JObject.Parse(value)

For Each Row2 In json("results").ToList()
    Response.Write(Row2("rating2").ToString() & "<br>")
Next
Response.Write(json("number_results"))

3 Ответов

Рейтинг:
28

Graeme_Grant

У меня есть вспомогательная функция для извлечения данных из JSON, которую я использую в своей статье: Работа с JSON в C# и VB[^]

Imports Newtonsoft.Json.Linq

Public Module JsonExtensions

    <Extension>
    Public Function FindTokens(containerToken As JToken, name As String) _
                        As List(Of JToken)

        Dim matches = New List(Of JToken)()
        FindTokens(containerToken, name, matches)
        Return matches

    End Function

    Private Sub FindTokens(containerToken As JToken, name As String, _
                           matches As List(Of JToken))

        If containerToken.Type = JTokenType.[Object] Then
            For Each child As JProperty In containerToken.Children(Of JProperty)()
                If child.Name = name Then
                    matches.Add(child.Value)
                End If
                FindTokens(child.Value, name, matches)
            Next
        ElseIf containerToken.Type = JTokenType.Array Then
            For Each child As JToken In containerToken.Children()
                FindTokens(child, name, matches)
            Next
        End If

    End Sub

End Module

Затем, чтобы использовать, вы просто делаете что-то вроде::
Dim tags As List(Of Single) = _
    JObject.Parse(rawJSON) _
           .FindTokens("rating2") _
           .Values(Of Single)() _
           .ToList()

ОБНОВЛЕНИЕ: Вот полный пример для вас, который вы можете подключить к тестовому консольному приложению:
Imports System.Runtime.CompilerServices
Imports Newtonsoft.Json.Linq

Module Module1

    Sub Main()

        Dim rawJSON = "{
            ""results"": [{
                ""rating2"": 6.66666,
                ""downloads_min"": 5000000,
                ""klm"": [{
                    ""top1"": ""mine""
                },
                {
                    ""top2"": ""yours""
                }]
            },
            {
                ""rating2"": 4.4444,
                ""downloads_min"": 505550000,
                ""klm"": [{
                    ""top1"": ""2mine""
                },
                {
                    ""top2"": ""2yours""
                }]
            },
            {
                ""rating2"": 900000,
                ""downloads_min"": 505550000,
                ""klm"": [{
                    ""top1"": ""mine""
                },
                {
                    ""top2"": ""yours""
                }]
            }],
            ""number_results"": 263,
            ""has_next"": true,
            ""page"": 1,
            ""num_pages"": 132,
            ""limit"": 2
        }"

        Dim tags As List(Of Single) =
            JObject.Parse(rawJSON) _
                   .FindTokens("rating2") _
                   .Values(Of Single)() _
                   .ToList()

        For Each tag In tags
            Console.WriteLine(tag)
        Next

    End Sub

End Module

Public Module JsonExtensions

    <Extension>
    Public Function FindTokens(containerToken As JToken, name As String) _
                        As List(Of JToken)

        Dim matches = New List(Of JToken)()
        FindTokens(containerToken, name, matches)
        Return matches

    End Function

    Private Sub FindTokens(containerToken As JToken, name As String,
                           matches As List(Of JToken))

        If containerToken.Type = JTokenType.[Object] Then
            For Each child As JProperty In containerToken.Children(Of JProperty)()
                If child.Name = name Then
                    matches.Add(child.Value)
                End If
                FindTokens(child.Value, name, matches)
            Next
        ElseIf containerToken.Type = JTokenType.Array Then
            For Each child As JToken In containerToken.Children()
                FindTokens(child, name, matches)
            Next
        End If

    End Sub

End Module

И выход есть:
6.66666
4.4444
900000


Member 10285969

Я попробовал этот ваш код, но он не дал мне никакого результата. мое приложение немного отличается от этого, я просто использую ваш помощник json, но он не работает. я думал, что смогу использовать его для извлечения всего, что угодно

Graeme_Grant

Это зависит от того, как вы его используете. Это закрытый вопрос, поэтому вам нужно будет опубликовать новый.

Рейтинг:
2

Member 14792456

   Imports System.Web.Script.Serialization

   Structure JSONStruct
    Structure resultsStruct
        Structure klmStruct
            Public top1 As String
            Public top2 As String
        End Structure
        Public rating2 As Decimal
        Public downloads_min As Integer
        Public klm As List(Of klmStruct)
    End Structure
    Public results As List(Of resultsStruct)
    Public number_results As Integer
    Public has_next As Boolean
    Public page As Integer
    Public num_pages As Integer
    Public limit As Integer
End Structure
Function test()

    Dim serializer As New JavaScriptSerializer

    Dim rawJSON = "{
        ""results"": [{
            ""rating2"": 6.66666,
            ""downloads_min"": 5000000,
            ""klm"": [{
                ""top1"": ""mine""
            },
            {
                ""top2"": ""yours""
            }]
        },
        {
            ""rating2"": 4.4444,
            ""downloads_min"": 505550000,
            ""klm"": [{
                ""top1"": ""2mine""
            },
            {
                ""top2"": ""2yours""
            }]
        },
        {
            ""rating2"": 900000,
            ""downloads_min"": 505550000,
            ""klm"": [{
                ""top1"": ""mine""
            },
            {
                ""top2"": ""yours""
            }]
        }],
        ""number_results"": 263,
        ""has_next"": true,
        ""page"": 1,
        ""num_pages"": 132,
        ""limit"": 2
    }"

    Dim json As JSONStruct = serializer.Deserialize(Of JSONStruct)(rawJSON)

    For Each result As JSONStruct.resultsStruct In json.results

        For Each klm As JSONStruct.resultsStruct.klmStruct In result.klm
            If klm.top1 IsNot Nothing Then
                Console.WriteLine(klm.top1)
            End If
            If klm.top2 IsNot Nothing Then
                Console.WriteLine(klm.top2)
            End If
        Next

    Next
End Function


выход:
мой
твой
2mine
2yours
мой
твой


CHill60

Где находится выход для top1 и top2, который требуется OP?

Member 14792456

Прямо под словами вывод:

Рейтинг:
1

jameskm69

Спасибо за ответ. Но я продолжаю получать:
FindTokens не является членом Newtonsoft.Json.Linq.


Я не знаю, что делаю не так. Десериализация происходит из события нажатия кнопки.
поэтому, когда я вызываю функцию FindTokens, я получаю эту ошибку.

Спасибо,


Richard Deeming

Если вы хотите ответить на решение, нажмите кнопку "ответить" под решением. НЕ опубликуйте свой комментарий как новое "решение".

Graeme_Grant

Работать отлично. Пожалуйста, обратите внимание, что я использую метод расширения. Если вы неправильно добавите его в свое приложение, вы увидите это сообщение об ошибке, как вы описываете.

См. раздел Обновление до решения 1 с полной версией копирования и вставки для консольного приложения.

jameskm69

Спасибо за ваш ответный пост. Да, это работает. Спасибо снова