2014-10-07 3 views
1

Я хочу начать с того, что не знаю, что я делаю. Я пытаюсь прочитать данные json от Twitch.tv. URL-адрес, с которым я сейчас работаю, выглядит так: https://api.twitch.tv/kraken/channels/seeingblue/followsОрганизация данных с использованием JSON.NET в VB.NET

В моей программе мне удалось десериализовать мои данные и сделать его удобным и понятным. У меня проблемы с хранением данных - это организованная мода. То, что я хочу сделать, - опросить URL-адрес на регулярном интервале и проверить любые изменения.

Мне удалось заставить этот пример работать, но я не могу изменить код для работы за то, что мне нужно. vb.net json.net parse results

Это то, что я в настоящее время:

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click 
    Try 
     Dim json As String = New WebClient().DownloadString("https://api.twitch.tv/kraken/channels/seeingblue/follows?limit=1&offset=0") 
     Dim root As JObject = JObject.Parse(json) 
     Dim stream As JToken = root("user") 
     Dim game As String = stream("name").ToString() 
     'Dim viewers As String = stream("_links").ToString() 
     MsgBox(game) 
    Catch ex As Exception 
     MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Error") 
    End Try 

End Sub 

Но я получаю сообщение об ошибке о Object reference not set to an instance of an object.

или если я пытаюсь

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click 
    Try 
     Dim json As String = New WebClient().DownloadString("https://api.twitch.tv/kraken/channels/seeingblue/follows?limit=1&offset=0") 
     Dim root As JObject = JObject.Parse(json) 
     Dim stream As JToken = root("follows") 
     Dim game As String = stream("created_at").ToString() 
     'Dim viewers As String = stream("_links").ToString() 
     MsgBox(game) 
    Catch ex As Exception 
     MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Error") 
    End Try 

End Sub 

Я получаю сообщение об ошибке с указанием Accessed JArray values with invalid key value: "created_at". Array position index expected. Can кто-то объясняет, что я здесь делаю неправильно?

+0

Вы не можете индексировать массивы по строкам. – Casey

+0

Итак, я думаю, что разница между ними - это пример не массива, а мой. Любая идея, как я могу это сделать? – Josh

ответ

2

Это может помочь рассмотреть форматированный JSON. Я вставил URL-адрес из вашего кода в окно валидатора в JSONLint.com и нажал «Подтвердить». Вот результат:

{ 
    "follows": [ 
     { 
      "created_at": "2014-10-02T17:15:10Z", 
      "_links": { 
       "self": "https://api.twitch.tv/kraken/users/sleepyynet/follows/channels/seeingblue" 
      }, 
      "user": { 
       "_id": 41403351, 
       "name": "sleepyynet", 
       "created_at": "2013-03-16T19:42:01Z", 
       "updated_at": "2014-10-07T19:28:33Z", 
       "_links": { 
        "self": "https://api.twitch.tv/kraken/users/sleepyynet" 
       }, 
       "display_name": "SleepyyNet", 
       "logo": "http://static-cdn.jtvnw.net/jtv_user_pictures/sleepyynet-profile_image-96061b55b0da4c11-300x300.png", 
       "bio": "Zzz...The Tired One", 
       "type": "user" 
      } 
     } 
    ], 
    "_total": 14, 
    "_links": { 
     "self": "https://api.twitch.tv/kraken/channels/seeingblue/follows?direction=DESC&limit=1&offset=0", 
     "next": "https://api.twitch.tv/kraken/channels/seeingblue/follows?direction=DESC&limit=1&offset=1" 
    } 
} 

Вы можете видеть из вышесказанного следует, что объект ответа JSON содержит три свойства: follows, _total и _links. Свойство follows содержит массив. Этот массив содержит объект, который имеет три свойства: created_at, _links и user. created_at - это строка, содержащая дату, а user и _links - оба объекта, содержащие еще больше свойств.

Учитывая это, давайте посмотрим, что делает ваш код.

В первом примере, вы делаете это:

Dim stream As JToken = root("user") 
Dim game As String = stream("name").ToString() 

Это терпит неудачу, потому что нет user собственности на корневом уровне JSON, так root("user") возвращает нулевое значение. Вы получаете исключение, когда пытаетесь использовать переменную null stream в следующей строке.

В вашем втором примере, вы делаете это:

Dim stream As JToken = root("follows") 
Dim game As String = stream("created_at").ToString() 

Это терпит неудачу, потому что root("follows") возвращает массив. Вы не можете индексировать JArray с именем строки; вы должны использовать числовой индекс (или же итерацию по массиву с использованием цикла For Each).


Как мы можем сделать эту работу? Давайте рассмотрим ваш первый пример.Для того, чтобы получить имя пользователя в первом пункте следует массив в корне ответа, вы можете сделать это:

Dim root As JToken = JToken.Parse(json) ' Parse the response 
Dim follows As JToken = root("follows") ' Get the "follows" array from the root 
Dim item As JToken = follows(0)   ' Get the first item of the array 
Dim user As JToken = item("user")   ' Get the user object from the item 
Dim name As String = user("name")   ' Get the name from the user object 
MsgBox(name)        ' Display the name 

Другой способ сделать то же самое с меньшим количеством кода, чтобы использовать удобный SelectToken метод для перехода к желаемому JToken используя синтаксис пути:

Dim root As JToken = JToken.Parse(json) 
Dim name As String = root.SelectToken("follows[0].user.name") 
MsgBox(name) 

конечно, оба из приведенных выше примеров, предположим, что у вас уже есть индекс элемента массива вы хотите. Если есть только один элемент, нет проблем - индекс 0. Но что, если в массиве есть несколько элементов? В этом случае вы, скорее всего, захотите сделать свою обработку в цикле. Вот пример, который отобразит имена всех пользователей, следующих за «seeblue».

Dim url As String = "https://api.twitch.tv/kraken/channels/seeingblue/follows" 
Dim json As String = New WebClient().DownloadString(url) 
Dim root As JToken = JToken.Parse(json) 
Dim sb As New StringBuilder() 

For Each item As JToken In root("follows") 
    sb.AppendLine(item.SelectToken("user.name")) 
Next 

MsgBox(sb.ToString()) 

Надеюсь, это поможет.

+0

Спасибо, очень легко понять. Я задержу это в течение нескольких часов, и я уверен, что смогу получить от него что-то полезное. – Josh

Смежные вопросы