2017-05-09 2 views
1

Ich weiß, dass es viele Antworten dazu gibt, aber ich kann die Antwort nicht analysieren.Probleme mit der JSON-Deserialisierung

Das ist meine JSON, die ich von wrGETURL.OpenRead(sURL) erhalten:

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

Das ist mein JSON, die ich von getcall.OpenRead(sURL) zurück:

 
{ 
    "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" 
     } 
    ] 
} 

Wenn ich die Zeile JsonConvert.DeserializeObject(Of TotalResponse)(st) und Ausgang auf Kommentar st zu einem MessageBox das ist mein JSON:

screenshot for json response

Wie Sie sehen können, ist es in Ordnung. Allerdings, wenn ich in dieser Zeile einen Kommentar zurück ich die folgende Fehlermeldung erhalten:

401 Unauthorized

Das ist mein voller Code:

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 

Das sind meine Klassen für die JSON-Antwort:

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 

Antwort

0

Ich würde in Betracht ziehen Using für Ihre WebClient und StreamReader Objekte zu implementieren:

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.

Bitte beachten Sie auch Option Strict On drehen, die Sie besseren Code schreiben helfen:

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

ich als ein allgemeines Exception bei Verwendung der JsonSerializationException in Ihrem Catch eher würde auch aussehen.

Mit Ihrer Methode getCustomers sollten Sie in eine Funktion wechseln und TotalResponse zurückgeben.

Schließlich betrachten nur Variablen deklarieren wenn sie gebraucht werden und nur, wenn sie benötigt werden. Dies hilft bei der Reduzierung der Code-Menge und des Workflows Ihres Codes. Dies kann besonders nützlich für das Debuggen sein.

Mit diesen Änderungen Ihr Code wie folgt aussehen würde:

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 

Ich habe auch festgestellt, Ihre SQL für SQL-Injection geöffnet ist. Es liegt jedoch außerhalb des Bereichs dieser Frage, die Verwendung von SQL-Parametern in Betracht zu ziehen. Ich bin nicht vertraut mit mobjHost.SetSQL so kann ich leider in diesem Bereich nicht beraten.