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

时间:2014-10-07 19:38:16

标签: vb.net json.net

我想首先说我不知道​​自己在做什么。我试图从Twitch.tv读取json数据。我目前使用的网址如下所示:https://api.twitch.tv/kraken/channels/seeingblue/follows

在我的程序中,我设法对我的数据进行反序列化,使其看起来整洁可读。我无法存储数据是一种有组织的方式。我想要做的是定期轮询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.有人可以解释我在这里做错了吗?

1 个答案:

答案 0 :(得分:2)

查看格式化的JSON可能会有所帮助。我将代码中的网址粘贴到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。当您尝试在以下行中使用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。但是如果数组中有多个项目怎么办?在这种情况下,您可能希望在循环中进行处理。这是一个示例,它将显示“seeingblue”之后所有用户的名称。

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())

希望这有帮助。