1

我无法反序列化这个 JSON。

JSON 看起来像这样:

{
    "ticker": {
        "high": 91.489,
        "low": 88.3,
        "avg": 89.8945,
        "vol": 233637.9876,
        "vol_cur": 2588.09448,
        "last": 90.48,
        "buy": 90.55,
        "sell": 90.48,
        "updated": 1372613806,
        "server_time": 1372613807
    }
}

我的功能是这样的:

Private Function Btce(ByVal Address As String) As String
    Dim rt As String = ""
    Dim out As String
    Dim wRequest As WebRequest
    Dim wResponse As WebResponse
    Dim SR As StreamReader
    Dim Time As Date

    Time = Now()
    wRequest = WebRequest.Create(Address)
    wResponse = wRequest.GetResponse

    SR = New StreamReader(wResponse.GetResponseStream)
    rt = SR.ReadToEnd
    SR.Close()

    Dim js As New System.Web.Script.Serialization.JavaScriptSerializer
    Dim testObj = js.Deserialize(rt, New Object().GetType())
    Dim high = testObj("High")
    Dim low = testObj("Low")
    Dim avg = testObj("Average")
    Dim vol = testObj("Volume")
    Dim last = testObj("Last")
    Dim buy = testObj("Buy")
    Dim sell = testObj("Sell")

    out = "Data from btc-e.com" + Environment.NewLine
    out += (Time) + Environment.NewLine
    out += "High: " + Environment.NewLine
    out += "Low: " + Environment.NewLine
    out += "Average: " + Environment.NewLine
    out += "Volume: " + Environment.NewLine
    out += "Last: " + Environment.NewLine
    out += "Buy: " + Environment.NewLine
    out += "Sell: "

    Return out
End Function

然后我在控制台中得到这个:

Microsoft.VisualBasic.dll 中出现“System.Collections.Generic.KeyNotFoundException”类型的未处理异常附加信息:字典中不存在给定键。

4

2 回答 2

1

问题之一是您在 testObj 中寻找“Average”,但在 JSON 中它是“avg”。而且您也在寻找“音量”,而不是“音量”。

此外,反序列化返回的数据不是一个直接的集合,它是一个 System.Collections.Dictionary(Of String, Object) ,其中每个代表 json 中的股票代码对象都有一个条目。

每个ticker 对象包含一个String Key 和一个Value,其中Value 是一个System.Collections.Generic.KeyValuePair,它是区分大小写的。值包含数据的集合(即“高”,9.4189)。

基于此,您的代码应如下所示:

    Dim js As New System.Web.Script.Serialization.JavaScriptSerializer
    Dim cObjects = js.Deserialize(rt, New Object().GetType())

    Dim counter As Integer
    Dim out As New System.Text.StringBuilder(1000)

    ' Use a stringbuilder to capture the output; much more efficient than constant string concat
    out.Append("Data from btc-e.com").AppendLine()

    For Each testObj In cObjects
        Dim high = testObj.Value("high")
        Dim low = testObj.Value("low")
        Dim avg = testObj.Value("avg")
        Dim vol = testObj.Value("vol")
        Dim last = testObj.Value("last")
        Dim buy = testObj.Value("buy")
        Dim sell = testObj.Value("sell")

        ' Since you will be processing multiple records, show something 
        ' in the output about where you are 
        counter += 1

        out.Append("Element ").Append(counter).AppendLine()
        out.Append(DateTime.Now).AppendLine()
        out.Append("High: ").Append(high).AppendLine()
        out.Append("Low: ").Append(low).AppendLine()
        out.Append("Average: ").Append(avg).AppendLine()
        out.Append("Volume: ").Append(vol).AppendLine()
        out.Append("Last: ").Append(last).AppendLine()
        out.Append("Buy: ").Append(buy).AppendLine()
        out.Append("Sell: ").Append(sell).AppendLine()
    Next

    Return out.ToString()
于 2013-06-30T18:22:43.063 回答
0
  1. 反序列化为对象图时,您可以使用DeserializeObject
  2. 您要查找的键不在您刚刚反序列化的对象下,但实际上是"ticker".
  3. 用于字典的默认相等比较器可能区分大小写。您可能希望在显式指定 时构造一个新字典StringComparer.***IgnoreCase,其中 *** 是或中Ordinal的任何一个。InvariantCultureCurrentCulture

例如:

Dim testObj = js.Deserialize(Of Dictionary(Of String, Dictionary(Of String, Single)))(rt)("ticker")

testObj = New Dictionary(Of String, Single)(testObj, StringComparer.InvariantCultureIgnoreCase)

Dim high = testObj("High")
于 2013-06-30T18:06:20.600 回答