2017-05-09 74 views
1

我知道有很多与此相关的答案,但是,我无法解析响应。JSON反序列化的问题

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

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

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

 
{ 
    "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)和输出stMessageBox这是我的JSON:

screenshot for json response

正如你所看到的那样。但是,如果我的评论早在该行出现以下错误:

401 Unauthorized

这是我的全码:

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 

回答

0

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

Managed resources are disposed of by the .NET Framework garbage collector (GC) without any extra coding on your part. You do not need a Using block for managed resources. However, you can still use a Using block to force the disposal of a managed resource instead of waiting for the garbage collector.

也请看看转弯Option Strict On这将帮助你编写更好的代码:

Restricts implicit data type conversions to only widening conversions, disallows late binding, and disallows implicit typing that results in an Object type.

我也想看看使用CatchJsonSerializationException而不是一般的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,所以不幸的是我不能在这方面提供建议。