如何用 2 个不同的键解析 Json?
How to parse Json with 2 different keys?
我正在尝试解析 this API
这基本上是一个带有“询问”和“出价”的订单簿。
我如何解析它们,将要价与出价分开?
例如 api 开始询问 属性
所以如果 Json 是 {"asks":[["0.00001555","3264400"],["0.00001556","3662200"],["0.00001573","3264400"]
我期待这样的输出:
[asks]
Price- Quantity
0.00001555 - 3264400
0.00001556 - 3662200
0.00001573 - 3264400
ecc
之后是"bids":[["0.00001325","300"],["0.00001313","100"],["0.00001312","1051400"],["0.00001311","1300000"],["0.0000131","9336700"]
所以我期待
[bids]
Price- Quantity
0.00001325- 300
0.00001313 - 100
0.00001312 - 1051400
0.00001311 - 1300000
0.0000131 - 9336700
ecc
我知道如何使用代码解析每个值:
Dim streamData As Stream = Nothing
Using http As HttpClient = New HttpClient
Dim url As String = "https://api.hotbit.io/api/v1/order.depth?market=KIBA/USDT&limit=100&interval=1e-8"
Dim t As Task(Of Stream) = http.GetStreamAsync(url)
streamData = t.Result
End Using
Dim jsonResponse As JsonNode = JsonNode.Parse(streamData)
Dim result As JsonObject = jsonResponse("result").AsObject
For Each kvp In result.AsEnumerable
c &= kvp.Value("key?!?!?!?").ToString & ", "
Next
但在这种情况下,没有我可以“解析”的键,而且值的格式为 ["Price", "Quantity"]
而且我也不知道如何在询价和出价之间拆分结果,也许将它们拆分为两个不同的 richtextboxes multiline ..
任何帮助,将不胜感激
谢谢
使用 JsonUtils 将为您创建 classes,然后您可以将它们复制到您的项目中。
在此实例中,它将创建:
Public Class Result
Public Property asks As String()()
Public Property bids As String()()
Public Property seqNum As Integer
Public Property prevSeqNum As Integer
Public Property lastTs As Double
End Class
Public Class Root
Public Property [error] As Object
Public Property result As Result
Public Property id As Integer
End Class
Please note having error
as a property name will throw a compiler error and so you'll need to wrap it in square brackets like [error]
.
您还可以大大简化您的代码:
Private Async Sub MyMethod()
Dim root As Root = Await GetJsonFromApi()
For each ask In root.result.asks
Console.WriteLine(ask(0))
Next
End Sub
Private Async Function GetJsonFromApi() As Task(Of Root)
Using http As New HttpClient()
Dim url As String = "https://api.hotbit.io/api/v1/order.depth?market=KIBA/USDT&limit=100&interval=1e-8"
Return Await http.GetFromJsonAsync(Of Root)(url)
End Using
End Function
或者,如果您愿意并希望处理异常,则类似:
Private Async Sub MyMethod()
Dim root As Root = Await GetJsonFromApi()
For each ask In root.result.asks
Next
End Sub
Private Async Function GetJsonFromApi() As Task(Of Root)
Using http As New HttpClient()
Dim url As String = "https://api.hotbit.io/api/v1/order.depth?market=KIBA/USDT&limit=100&interval=1e-8"
Dim response As HttpResponseMessage = Await http.GetAsync(url)
If response.IsSuccessStatusCode
Return Await response.Content.ReadFromJsonAsync(Of Root)
End If
End Using
Return New Result
End Function
附带说明一下,我正在等待您可以通过关键字 Await 看到的回复。我更喜欢这样做而不是在最后调用 .Result
。
最后,我会考虑将 url
变量设为常量:
Private Const URI As String = "https://api.hotbit.io/api/v1/order.depth?market=KIBA/USDT&limit=100&interval=1e-8"
...
Dim response As HttpResponseMessage = Await http.GetAsync(URI)
还有 Newtonsoft.Json 可以用来将 JSON 反序列化为 class:
Private Async Function GetJsonFromApi() As Task(Of Root)
Using http As New HttpClient(),
response As HttpResponseMessage = await http.GetAsync(URI)
Return JsonConvert.DeserializeObject(Of Root)(Await response.Content.ReadAsStringAsync())
End Using
End Function
Note you will have to add this as a Nuget package to your application. Also I've assumed the URI is now a constant and I've nested the Using
statements.
要输出这些你必须使用String.Join and to ensure the UI doesn't freeze you can call Control.BeginInvoke:
Private Sub OutputAsks(asks As String()())
Dim contents As New StringBuilder
contents.AppendLine("[asks]")
contents.AppendLine("Price - Quantity")
For Each ask In asks
contents.AppendLine(String.Join(" - ", ask))
Next
RichTextBox1.BeginInvoke(Sub()
RichTextBox1.Text = contents.ToString()
End Sub)
End Sub
Private Sub OutputBids(bids As String()())
Dim contents As New StringBuilder
contents.AppendLine("[bids]")
contents.AppendLine("Price - Quantity")
For Each bid In bids
contents.AppendLine(String.Join(" - ", bid))
Next
RichTextBox2.BeginInvoke(Sub()
RichTextBox2.Text = contents.ToString()
End Sub)
End Sub
Note, as part of the Control.BeginInvoke
you don't have to strictly call Control.EndInvoke
as noted in the docs:
You can call EndInvoke to retrieve the return value from the delegate, if neccesary, but this is not required. EndInvoke will block until the return value can be retrieved.
完整的解决方案 - 考虑到您的 Button
、Timer
和 RichTextbox
控件 - 看起来像:
Private Const URI As String = "https://api.hotbit.io/api/v1/order.depth?market=KIBA/USDT&limit=10&interval=1e-8"
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Timer1.Start()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
UpdateContents()
End Sub
Private Async Sub UpdateContents()
Dim jsonContents As String = Await GetJsonFromApi()
Dim root As Root = DeserialiseJsonToRoot(jsonContents)
OutputAsks(root.result.asks)
OutputBids(root.result.bids)
End Sub
Private Async Function GetJsonFromApi() As Task(Of String)
Using http As New HttpClient(),
response As HttpResponseMessage = Await http.GetAsync(URI)
Return Await response.Content.ReadAsStringAsync()
End Using
End Function
Private Function DeserialiseJsonToRoot(json As String) As Root
Return JsonConvert.DeserializeObject(Of Root)(json)
End Function
Private Sub OutputAsks(asks As String()())
Dim contents As New StringBuilder
contents.AppendLine("[asks]")
contents.AppendLine("Price - Quantity")
For Each ask In asks
contents.AppendLine(String.Join(" - ", ask))
Next
RichTextBox1.BeginInvoke(Sub()
RichTextBox1.Text = contents.ToString()
End Sub)
End Sub
Private Sub OutputBids(bids As String()())
Dim contents As New StringBuilder
contents.AppendLine("[bids]")
contents.AppendLine("Price - Quantity")
For Each bid In bids
contents.AppendLine(String.Join(" - ", bid))
Next
RichTextBox2.BeginInvoke(Sub()
RichTextBox2.Text = contents.ToString()
End Sub)
End Sub
我正在尝试解析 this API
这基本上是一个带有“询问”和“出价”的订单簿。
我如何解析它们,将要价与出价分开?
例如 api 开始询问 属性
所以如果 Json 是 {"asks":[["0.00001555","3264400"],["0.00001556","3662200"],["0.00001573","3264400"]
我期待这样的输出:
[asks]
Price- Quantity
0.00001555 - 3264400
0.00001556 - 3662200
0.00001573 - 3264400
ecc
之后是"bids":[["0.00001325","300"],["0.00001313","100"],["0.00001312","1051400"],["0.00001311","1300000"],["0.0000131","9336700"]
所以我期待
[bids]
Price- Quantity
0.00001325- 300
0.00001313 - 100
0.00001312 - 1051400
0.00001311 - 1300000
0.0000131 - 9336700
ecc
我知道如何使用代码解析每个值:
Dim streamData As Stream = Nothing
Using http As HttpClient = New HttpClient
Dim url As String = "https://api.hotbit.io/api/v1/order.depth?market=KIBA/USDT&limit=100&interval=1e-8"
Dim t As Task(Of Stream) = http.GetStreamAsync(url)
streamData = t.Result
End Using
Dim jsonResponse As JsonNode = JsonNode.Parse(streamData)
Dim result As JsonObject = jsonResponse("result").AsObject
For Each kvp In result.AsEnumerable
c &= kvp.Value("key?!?!?!?").ToString & ", "
Next
但在这种情况下,没有我可以“解析”的键,而且值的格式为 ["Price", "Quantity"] 而且我也不知道如何在询价和出价之间拆分结果,也许将它们拆分为两个不同的 richtextboxes multiline .. 任何帮助,将不胜感激 谢谢
使用 JsonUtils 将为您创建 classes,然后您可以将它们复制到您的项目中。
在此实例中,它将创建:
Public Class Result
Public Property asks As String()()
Public Property bids As String()()
Public Property seqNum As Integer
Public Property prevSeqNum As Integer
Public Property lastTs As Double
End Class
Public Class Root
Public Property [error] As Object
Public Property result As Result
Public Property id As Integer
End Class
Please note having
error
as a property name will throw a compiler error and so you'll need to wrap it in square brackets like[error]
.
您还可以大大简化您的代码:
Private Async Sub MyMethod()
Dim root As Root = Await GetJsonFromApi()
For each ask In root.result.asks
Console.WriteLine(ask(0))
Next
End Sub
Private Async Function GetJsonFromApi() As Task(Of Root)
Using http As New HttpClient()
Dim url As String = "https://api.hotbit.io/api/v1/order.depth?market=KIBA/USDT&limit=100&interval=1e-8"
Return Await http.GetFromJsonAsync(Of Root)(url)
End Using
End Function
或者,如果您愿意并希望处理异常,则类似:
Private Async Sub MyMethod()
Dim root As Root = Await GetJsonFromApi()
For each ask In root.result.asks
Next
End Sub
Private Async Function GetJsonFromApi() As Task(Of Root)
Using http As New HttpClient()
Dim url As String = "https://api.hotbit.io/api/v1/order.depth?market=KIBA/USDT&limit=100&interval=1e-8"
Dim response As HttpResponseMessage = Await http.GetAsync(url)
If response.IsSuccessStatusCode
Return Await response.Content.ReadFromJsonAsync(Of Root)
End If
End Using
Return New Result
End Function
附带说明一下,我正在等待您可以通过关键字 Await 看到的回复。我更喜欢这样做而不是在最后调用 .Result
。
最后,我会考虑将 url
变量设为常量:
Private Const URI As String = "https://api.hotbit.io/api/v1/order.depth?market=KIBA/USDT&limit=100&interval=1e-8"
...
Dim response As HttpResponseMessage = Await http.GetAsync(URI)
还有 Newtonsoft.Json 可以用来将 JSON 反序列化为 class:
Private Async Function GetJsonFromApi() As Task(Of Root)
Using http As New HttpClient(),
response As HttpResponseMessage = await http.GetAsync(URI)
Return JsonConvert.DeserializeObject(Of Root)(Await response.Content.ReadAsStringAsync())
End Using
End Function
Note you will have to add this as a Nuget package to your application. Also I've assumed the URI is now a constant and I've nested the
Using
statements.
要输出这些你必须使用String.Join and to ensure the UI doesn't freeze you can call Control.BeginInvoke:
Private Sub OutputAsks(asks As String()())
Dim contents As New StringBuilder
contents.AppendLine("[asks]")
contents.AppendLine("Price - Quantity")
For Each ask In asks
contents.AppendLine(String.Join(" - ", ask))
Next
RichTextBox1.BeginInvoke(Sub()
RichTextBox1.Text = contents.ToString()
End Sub)
End Sub
Private Sub OutputBids(bids As String()())
Dim contents As New StringBuilder
contents.AppendLine("[bids]")
contents.AppendLine("Price - Quantity")
For Each bid In bids
contents.AppendLine(String.Join(" - ", bid))
Next
RichTextBox2.BeginInvoke(Sub()
RichTextBox2.Text = contents.ToString()
End Sub)
End Sub
Note, as part of the
Control.BeginInvoke
you don't have to strictly callControl.EndInvoke
as noted in the docs:You can call EndInvoke to retrieve the return value from the delegate, if neccesary, but this is not required. EndInvoke will block until the return value can be retrieved.
完整的解决方案 - 考虑到您的 Button
、Timer
和 RichTextbox
控件 - 看起来像:
Private Const URI As String = "https://api.hotbit.io/api/v1/order.depth?market=KIBA/USDT&limit=10&interval=1e-8"
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Timer1.Start()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
UpdateContents()
End Sub
Private Async Sub UpdateContents()
Dim jsonContents As String = Await GetJsonFromApi()
Dim root As Root = DeserialiseJsonToRoot(jsonContents)
OutputAsks(root.result.asks)
OutputBids(root.result.bids)
End Sub
Private Async Function GetJsonFromApi() As Task(Of String)
Using http As New HttpClient(),
response As HttpResponseMessage = Await http.GetAsync(URI)
Return Await response.Content.ReadAsStringAsync()
End Using
End Function
Private Function DeserialiseJsonToRoot(json As String) As Root
Return JsonConvert.DeserializeObject(Of Root)(json)
End Function
Private Sub OutputAsks(asks As String()())
Dim contents As New StringBuilder
contents.AppendLine("[asks]")
contents.AppendLine("Price - Quantity")
For Each ask In asks
contents.AppendLine(String.Join(" - ", ask))
Next
RichTextBox1.BeginInvoke(Sub()
RichTextBox1.Text = contents.ToString()
End Sub)
End Sub
Private Sub OutputBids(bids As String()())
Dim contents As New StringBuilder
contents.AppendLine("[bids]")
contents.AppendLine("Price - Quantity")
For Each bid In bids
contents.AppendLine(String.Join(" - ", bid))
Next
RichTextBox2.BeginInvoke(Sub()
RichTextBox2.Text = contents.ToString()
End Sub)
End Sub