在VB.NET中使用JSON.NET组织数据

问题描述:

我想先说我不知道​​我在做什么。我正在尝试从Twitch.tv读取json数据。我目前使用的URL如下所示:https://api.twitch.tv/kraken/channels/seeingblue/follows在VB.NET中使用JSON.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.灿有人解释我在这里做错了什么?

+0

你不能通过字符串索引数组。 – Casey 2014-10-07 20:10:18

+0

所以我猜两者之间的区别是这个例子不是数组而是我的。任何想法我怎么能做到这一点呢? – Josh 2014-10-07 20:33:43

这可能有助于查看格式化的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_linksfollows属性包含一个数组。该数组包含一个对象,该对象具有三个属性:created_at_linksusercreated_at是包含日期的字符串,而user_links都是包含更多属性的对象。

考虑到这一点,我们来看看你的代码在做什么。

在你的第一个例子,你这样做是:

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

失败的原因是没有在JSON的根级别没有user属性,因此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。但是如果数组中有多个项目呢?在这种情况下,您可能会想要在循环中进行处理。这里有一个例子,它将显示“seesblue”后面的所有用户的名字。

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 2014-10-08 15:49:14