将 JSON 反序列化为模块

Deserialize JSON to a module

我需要解析来自加密货币交易所 API 的 JSON。 在这种情况下,我需要解析我的未结订单。 如果没有未结订单,则 Json 为:

{"error":null,"result":{"KIBAUSDT":{"limit":100,"offset":0,"total":0,"records":null}},"id":299639536}

这好像是一本字典。 一旦我创建了 1 个订单,Json 就会变成这样:

{"error":null,"result":{"KIBAUSDT":{"limit":100,"offset":0,"total":1,"records":[{"user":2996434,"id":82651361103,"market":"KIBAUSDT","freeze":"0.001","fee_stock":"","source":"web","type":1,"side":2,"ctime":1645022087.403207,"mtime":1645022087.403207,"price":"0.00001","amount":"100","taker_fee":"0.0035","maker_fee":"-0.003","left":"100","deal_stock":"0","deal_money":"0","deal_fee":"0","alt_fee":"0","deal_fee_alt":"0","status":0}]}},"id":305636871}

这看起来更像是一个数组(如果我错了请纠正我)。这些行是为我正在创建的每个订单创建的。 因此,在 quicktype.io, I'm setting the option as array, converting it to vb.net using Icsharpcode 上,创建一个 class 文件,并考虑 属性“总计”,因为如果有或没有打开订单,这很容易理解。 将 c# 翻译成 vb.net:

Imports System
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Converters
Imports System.Runtime.CompilerServices

Namespace QuickType
    Partial Public Class Example
        <JsonProperty("error")>
        Public Property [Error] As Object
        <JsonProperty("result")>
        Public Property Result As Result
        <JsonProperty("id")>
        Public Property Id As Long
    End Class

    Partial Public Class Result
        <JsonProperty("KIBAUSDT")>
        Public Property Kibausdt As Kibausdt
    End Class

    Partial Public Class Kibausdt
        <JsonProperty("limit")>
        Public Property Limit As Long
        <JsonProperty("offset")>
        Public Property Offset As Long
        <JsonProperty("total")>
        Public Property Total As Long
        <JsonProperty("records")>
        Public Property Records As Record()
    End Class

    Partial Public Class Record
        <JsonProperty("user")>
        Public Property User As Long
        <JsonProperty("id")>
        Public Property Id As Long
        <JsonProperty("market")>
        Public Property Market As String
        <JsonProperty("freeze")>
        Public Property Freeze As String
        <JsonProperty("fee_stock")>
        Public Property FeeStock As String
        <JsonProperty("source")>
        Public Property Source As String
        <JsonProperty("type")>
        Public Property Type As Long
        <JsonProperty("side")>
        Public Property Side As Long
        <JsonProperty("ctime")>
        Public Property Ctime As Double
        <JsonProperty("mtime")>
        Public Property Mtime As Double
        <JsonProperty("price")>
        Public Property Price As String
        <JsonProperty("amount")>
        <JsonConverter(GetType(ParseStringConverter))>
        Public Property Amount As Long
        <JsonProperty("taker_fee")>
        Public Property TakerFee As String
        <JsonProperty("maker_fee")>
        Public Property MakerFee As String
        <JsonProperty("left")>
        <JsonConverter(GetType(ParseStringConverter))>
        Public Property Left As Long
        <JsonProperty("deal_stock")>
        <JsonConverter(GetType(ParseStringConverter))>
        Public Property DealStock As Long
        <JsonProperty("deal_money")>
        <JsonConverter(GetType(ParseStringConverter))>
        Public Property DealMoney As Long
        <JsonProperty("deal_fee")>
        <JsonConverter(GetType(ParseStringConverter))>
        Public Property DealFee As Long
        <JsonProperty("alt_fee")>
        <JsonConverter(GetType(ParseStringConverter))>
        Public Property AltFee As Long
        <JsonProperty("deal_fee_alt")>
        <JsonConverter(GetType(ParseStringConverter))>
        Public Property DealFeeAlt As Long
        <JsonProperty("status")>
        Public Property Status As Long
    End Class

    Partial Public Class Example
        Public Shared Function FromJson(ByVal json As String) As Example
            Return JsonConvert.DeserializeObject(Of Example)(json, Settings)
        End Function
    End Class

    Public Module Serialize
        <Extension()>
        Public Function ToJson(ByVal self As Example) As String
            Return JsonConvert.SerializeObject(self, Settings)
        End Function
    End Module

    Friend Module Converter
        Public ReadOnly Settings As JsonSerializerSettings = New JsonSerializerSettings With {
            .MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
            .DateParseHandling = DateParseHandling.None
        }
    End Module

    Friend Class ParseStringConverter
        Inherits JsonConverter

        Public Overrides Function CanConvert(ByVal t As Type) As Boolean
            Return t Is GetType(Long) OrElse t Is GetType(Long?)
        End Function

        Public Overrides Function ReadJson(ByVal reader As JsonReader, ByVal t As Type, ByVal existingValue As Object, ByVal serializer As JsonSerializer) As Object
            If reader.TokenType = JsonToken.Null Then Return Nothing
            Dim value = serializer.Deserialize(Of String)(reader)
            Dim l As Long

            If Long.TryParse(value, l) Then
                Return l
            End If

            Throw New Exception("Cannot unmarshal type long")
        End Function

        Public Overrides Sub WriteJson(ByVal writer As JsonWriter, ByVal untypedValue As Object, ByVal serializer As JsonSerializer)
            If untypedValue Is Nothing Then
                serializer.Serialize(writer, Nothing)
                Return
            End If

            Dim value = CLng(untypedValue)
            serializer.Serialize(writer, value.ToString())
            Return
        End Sub

        Public Shared ReadOnly Singleton As ParseStringConverter = New ParseStringConverter()
    End Class
End Namespace

现在问题开始了,因为.. Total 属性 在 Partial Public Class Kibausdt ,所以在解析打开的订单之前(价格、数量、状态是唯一的 属性 我有兴趣从 部分 Public Class Record ) 我想知道“总数” 属性 是否等于 0.

我仍然没有得到结果,我能去的最接近的是


 Dim downloadTasks As New List(Of Task(Of String))
             Dim s = wc.DownloadStringTaskAsync("https://api.hotbit.io/api/v1/order.pending?market=KIBA/USDT&offset=0&limit=100&api_key=44812d8f-66d3-01c0-94c3b29305040b03&sign=F3330B924E1873B9C8FAB40A25D7B851")
             downloadTasks.Add(s)
             Await Task.WhenAll(downloadTasks)
             Dim total = Kibausdt.FromJson((Await s))
        
             If zeroOpenOrders As Long In total = "0" Then
                 RichTextBox1.Text = "0 opened orders"
             Else
                 For Each r As Result In Record.Result
                     Dim side As String = r("side").AsValue.ToString
                     Dim amount As Long = CInt(r("amount").AsValue.ToString)
                     Dim price As String = r("price").AsValue.ToString
                     RichTextBox1.Text &= side & amount & price
                 Next
             End If

我收到了这些错误:

第一个错误“FromJson 不是 kibausdt 的成员”有点奇怪,因为总数 属性 在 Kibausdt class 中。使用 Dim total = Example.FromJson((Await s)) 解决了这个问题,但我不确定这就是答案。

谢谢

Public Async Function ExecuteAsync() As Task
    Dim wc As New WebClient
    'you can await this task and get the json string result instead of adding it to a list first
    Dim json = Await wc.DownloadStringTaskAsync("https://api.hotbit.io/api/v1/order.pending?market=KIBA/USDT&offset=0&limit=100&api_key=44812d8f-66d3-01c0-94c3b29305040b03&sign=F3330B924E1873B9C8FAB40A25D7B851")

    'deserialize the json
    Dim rootObject = Example.FromJson(json)
    'navigate to Kibausdt
    Dim kibausdt = rootObject.result.KIBAUSDT

    'check total
    If kibausdt.total = 0 Then
        RichTextBox1.Text = "0 opened orders"
    Else
        'loop through records
        For Each record In kibausdt.records
            Dim side As String = record.side.ToString()
            Dim amount As Long = record.amount
            Dim price As String = record.price
            RichTextBox1.Text &= side & amount & price
        Next
    End If
End Function