字典中没有给定的密钥?

时间:2013-06-30 18:02:13

标签: json vb.net

我无法反序列化此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”类型异常   附加信息:字典中没有给定的密钥。

2 个答案:

答案 0 :(得分:1)

其中一个问题是你正在寻找"平均"在testObj中,但在JSON中它是" avg"。你也在寻找" Volume"而不是" vol"。

此外,反序列化返回的数据不是直接集合,它是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()

答案 1 :(得分:0)

  1. 反序列化为对象图时,您只需使用DeserializeObject
  2. 即可
  3. 您要查找的密钥不在您刚刚反序列化的对象下,但实际上是"ticker"下对象的键。
  4. 用于词典的默认相等比较器可能区分大小写。您可能希望在明确指定StringComparer.***IgnoreCase时构建新词典,其中***是OrdinalInvariantCultureCurrentCulture中的任意一个。
  5. 例如:

    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")