JSON反序列化的问题

时间:2017-05-09 09:23:59

标签: json vb.net parsing json.net

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

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

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

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

{
    "success": true,
    "message": "OK",
    "total": 1,
    "data": [
        {
            "domain": "emailsecautomate.co",
            "status": "Active",
            "order_date": "2017-04-26",
            "service": "Email Security",
            "company_name": "some name",
            "address1": "1 somewhere",
            "address2": null,
            "city": "somecity",
            "state": null,
            "country": "some country",
            "post_code": null,
            "telephone": null,
            "email": null,
            "po_number": null,
            "licenses": "10"
        }
    ]
}

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

screenshot for json response

你可以看到它很好。但是,如果我在该行中发表评论,我会收到以下错误:

  

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

1 个答案:

答案 0 :(得分:0)

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

  

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

请同时查看Option Strict On,这将有助于您编写更好的代码:

  

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

我还会考虑使用JsonSerializationException中的Catch而非普通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所以不幸的是我不能在这方面提出建议。