【问题标题】:{"Unexpected JSON token when reading DataTable. Expected StartArray, got Integer. Path 'id', line 1, position 9."}{“读取 DataTable 时出现意外 JSON 令牌。预期 StartArray,得到整数。路径 'id',第 1 行,位置 9。”}
【发布时间】:2021-08-28 06:57:26
【问题描述】:

在将 json 反序列化为数据集时收到以下错误。

Unexpected JSON token when reading DataTable. Expected StartArray, got Integer. Path 'id', line 1, position 9

Json 检索到:{"id":130,"type":"general","setup":"test?","punchline":"test."}

我的代码

    Dim wc As New WebClient
    Try

        Dim res As String
        For i = 0 To 5
            res =  wc.DownloadString("https://official-joke-api.appspot.com/random_joke")

            Dim jObject = JsonConvert.DeserializeObject(res)

            Dim ds As New DataSet
            ds = JsonConvert.DeserializeObject(Of DataSet)(res)

            MsgBox(ds.Tables.Count)
        Next
    Catch ex As Exception
        MsgBox(ex)
    End Try

【问题讨论】:

  • 创建一个类 Joke,其属性为 id,type,setuppunchlineJsonConvert.DeserializeObject(Of Joke)(res),然后在每次迭代中将其添加到List<Joke>
  • 您可能应该使用Dictionary<int, class>,使用JSON 响应的Id 作为Key,这样您就可以避免两次添加相同的对象,以防出现重复。
  • @AkshayGaonkar,如果我必须将其转换为列表,那么我可以使用这个权利! Dim jObject = JsonConvert.DeserializeObject(Of JObject)(res).Root.ToList()
  • API 端点正在返回单个记录。您必须在反序列化后将每条记录添加到列表对象中,而不是每次都将其转换为列表。

标签: vb.net json.net dataset


【解决方案1】:

作为用户 Akshay Gaonkar commented,您可以为 Newtonsoft.Json 提供一个名为 Joke 的类来反序列化。您可以通过使用<JsonProperty("nameInTheJson")> 装饰属性来解决大写/小写首字母命名约定不匹配的问题。

您可以保持简单并创建一个List(Of Joke),而不是将数据反序列化到数据集中的数据表中。

这是一个控制台应用程序:

Imports System.Net
Imports Newtonsoft.Json

Module Program

    Class Joke
        <JsonProperty("id")>
        Property Id As Integer

        <JsonProperty("type")>
        Property Type As String

        <JsonProperty("setup")>
        Property Setup As String

        <JsonProperty("punchline")>
        Property Punchline As String

    End Class

    Sub Main(args As String())
        Dim jokes As New List(Of Joke)

        Using wc As New WebClient()
            For i = 1 To 5
                Dim jokeInfo = wc.DownloadString("https://official-joke-api.appspot.com/random_joke")
                jokes.Add(JsonConvert.DeserializeObject(Of Joke)(jokeInfo))
            Next
        End Using

        ' Alternative which fetches ten jokes in one go - note the use of (Of List(Of Joke))
        'Using wc As New WebClient()
        '    Dim jokeInfo = wc.DownloadString("https://official-joke-api.appspot.com/jokes/ten")
        '    jokes = JsonConvert.DeserializeObject(Of List(Of Joke))(jokeInfo)
        'End Using

        For Each jk In jokes
            Console.WriteLine($"{jk.Setup}{vbCrLf}{jk.Punchline}{vbCrLf}")
        Next

    End Sub

End Module

Using statement 是必需的,因为 WebClient 在使用后应该被丢弃以清理系统资源。 (您可以使用等效的 Try...Finallywc.Dispose()。)

【讨论】:

  • 如果我必须将其转换为列表,那么我可以使用这个权利! Dim jObject = JsonConvert.DeserializeObject(Of JObject)(res).Root.ToList()
  • @Riya 从服务器检索到数据后,您想对数据做什么?
【解决方案2】:

您显示的 JSON 无效。 Datatable 需要 Object 数组,因此 JSON 应如下所示:

[{"id":130,"type":"general","setup":"test?","punchline":"test."}]

【讨论】:

  • @Akshay Gaonkar 是的,你可以。当 JSON 包含某些特定类型时,可能会出现一些转换问题,或者如果数组中的第一个为空,则可能会错误地识别某些类型。对于使用通用类型和非空属性值的简单对象,反序列化会产生预期的结果。
  • @ tushar,有没有办法将其转换为数组? span>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-09
  • 2021-02-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多