我知道有很多与此相关的答案,但是,我无法解析答案。
这是我从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:
你可以看到它很好。但是,如果我在该行中发表评论,我会收到以下错误:
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
答案 0 :(得分:0)
我会考虑为您的WebClient
和StreamReader
对象实施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
所以不幸的是我不能在这方面提出建议。