【问题标题】:Issues with JSON deserializationJSON反序列化的问题
【发布时间】:2017-05-09 09:23:58
【问题描述】:

我知道有很多与此相关的答案,但是,我无法解析响应。

这是我从wrGETURL.OpenRead(sURL) 返回的 JSON:

{
    "sessionKey": "TFtG+pGZ0cl0TuUbItWGy9xb9RyoPKGlY2EUF/nHe"
}

这是我从getcall.OpenRead(sURL) 返回的 JSON:

{ “成功”:是的, “消息”:“好的”, “总数”:1, “数据”: [ { “域”:“emailsecautomate.co”, “状态”:“活动”, "order_date": "2017-04-26", “服务”:“电子邮件安全”, "company_name": "某个名字", "address1": "1 某处", “地址2”:空, “城市”:“某个城市”, “状态”:空, “国家”:“某个国家”, “post_code”:空, “电话”:空, “电子邮件”:空, “po_number”:空, “许可证”:“10” } ] }

如果我注释掉JsonConvert.DeserializeObject(Of TotalResponse)(st) 行并将st 输出到MessageBox,这就是我的JSON:

如您所见,这很好。但是,如果我在该行中发表评论,则会收到以下错误:

401 未经授权

这是我的完整代码:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    user = username.Text
    pwd = password.Text

    'MessageBox.Show(savedUser)
    If savedUser IsNot Nothing AndAlso savedUser = "-9999" Then
        Dim sqlStatement As String = "INSERT INTO my_table VALUES ('" & user & "','" & pwd & "')"
        mobjHost.SetSQL(sqlStatement)
    End If

    Dim encoded As String = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(user + ":" + pwd))

    Dim sURL As String
    sURL = "https://xxx.xxx/partners/auth"

    Dim wrGETURL As New WebClient()

    wrGETURL.Headers.Add("Authorization", "Basic " + encoded)

    Try
        Dim data As Stream = wrGETURL.OpenRead(sURL)
        Dim reader As New StreamReader(data)
        Dim s As String = reader.ReadToEnd()

        Dim jsonResult = JsonConvert.DeserializeObject(Of IDictionary)(s)
        'This line with/without ToString gives the error "objectreference is not set to an instance of Object"
        Dim sessionKey = jsonResult.Item("sessionKey").ToString
        'Not calling the function for now As even session key gives the same issue
        'MessageBox.Show(sessionKey) This shows the sessionKey and everything is fine if this is used
        'Me.getCustomers(sessionKey)
        wrGETURL.Dispose()


    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try

End Sub

Public Function getCustomers(ByVal sKey As String)
    Dim st As String = ""
    Dim getcall As New WebClient()
    getcall.Headers.Add("USER", user)
    getcall.Headers.Add("KEY", sKey)
    getcall.Headers.Add("Content-Type", "application/json")
    Dim sURL = "https://xxx.xxx/partners/customers"
    Try
        Dim data As Stream = getcall.OpenRead(sURL)
        Dim reader As New StreamReader(data)
        st = reader.ReadToEnd()

        theResponse = JsonConvert.DeserializeObject(Of TotalResponse)(st)


    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try

    Return True
End Function

这些是我的 JSON 响应类:

Public Class TotalResponse
    Public success As String
    Public message As String
    Public total As String
    Public data As List(Of CustomerInfo)
End Class


Public Class CustomerInfo
    Public domain As String
    Public status As String
    Public order_date As String
    Public service As String
    Public company_name As String
    Public address1 As String
    Public address2 As String
    Public city As String
    Public state As String
    Public country As String
    Public post_code As String
    Public telephone As String
    Public email As String
    Public po_number As String
    Public licenses As String

End Class

【问题讨论】:

    标签: json vb.net parsing json.net


    【解决方案1】:

    我会考虑为您的WebClientStreamReader 对象实现Using

    托管资源由 .NET Framework 垃圾收集器 (GC) 处理,无需您进行任何额外编码。托管资源不需要 Using 块。但是,您仍然可以使用 Using 块来强制处置托管资源,而不是等待垃圾收集器。

    还请看转Option Strict On,这将帮助您编写更好的代码:

    将隐式数据类型转换限制为仅扩展转换,禁止后期绑定,并禁止导致 Object 类型的隐式类型。

    我还会考虑在您的Catch 中使用JsonSerializationException,而不是一般的Exception

    使用您的方法getCustomers,考虑将其更改为函数并返回TotalResponse

    最后考虑只声明变量如果需要它们,需要它们。这有助于减少代码量和代码的工作流程。这对于调试特别有用。

    通过这些更改,您的代码将如下所示:

    Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    
        Dim sessionKey As String = ""
        Using wb As New WebClient()
            Dim encoded As String = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(user + ":" + pwd))
            wb.Headers.Add("Authorization", "Basic " + encoded)
    
            Dim data As Stream = wb.OpenRead("https://xxx.xxx/partners/auth")
            Using reader As New StreamReader(data)
                Try
                    Dim result As IDictionary = JsonConvert.DeserializeObject(Of IDictionary)(Await reader.ReadToEndAsync())
    
                    sessionKey = result.Item("sessionKey").ToString()
                Catch ex As JsonSerializationException
                    'handle
                End Try
            End Using
        End Using
    
        If Not sessionKey = "" Then
            Dim theResponse As TotalResponse = getCustomers(sessionKey)
        End If
    
    End Sub
    
    Private Async Function getCustomers(ByVal sKey As String) As TotalResponse
    
        Dim returnResponse As New TotalResponse
    
        Using wb As New WebClient()
            wb.Headers.Add("USER", user)
            wb.Headers.Add("KEY", sKey)
            wb.Headers.Add("Content-Type", "application/json")
    
            Dim data As Stream = wb.OpenRead("https://api-dev.theemaillaundry.net/partners/customers")
            Using reader As New StreamReader(data)
                Try
                    returnResponse = JsonConvert.DeserializeObject(Of TotalResponse)(reader.ReadToEndAsync())
                Catch ex As JsonSerializationException
                    'handle
                End Try
            End Using
        End Using
    
        Return returnResponse
    
    End Function
    

    我还注意到您的 SQL 对 SQL 注入开放。它超出了这个问题的范围,但是考虑使用 SQL 参数。我不熟悉mobjHost.SetSQL,所以很遗憾我无法在这方面提供建议。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-23
      • 2021-05-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多