Json 字典中不存在给定的键?

Json 字典中不存在给定的键?,json,vb.net,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, "upda

我无法反序列化此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”的未处理异常 其他信息:字典中不存在给定的密钥

  • 当反序列化到对象图时,您只需使用
    反序列化对象
  • 您正在查找的键不在您刚刚反序列化的对象下,实际上是
    “ticker”
    下对象的键
  • 字典使用的默认相等比较器可能区分大小写。您可能希望在显式指定
    StringComparer.**IgnoreCase
    的同时构造一个新字典,其中***是
    序数
    不变量区域性
    当前区域性
    中的任意一个
  • 例如:

    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")
    
  • 当反序列化到对象图时,您只需使用
    反序列化对象
  • 您正在查找的键不在您刚刚反序列化的对象下,实际上是
    “ticker”
    下对象的键
  • 字典使用的默认相等比较器可能区分大小写。您可能希望在显式指定
    StringComparer.**IgnoreCase
    的同时构造一个新字典,其中***是
    序数
    不变量区域性
    当前区域性
    中的任意一个
  • 例如:

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

    其中一个问题是,您在testObj中查找的是“Average”,而在JSON中则是“avg”。你也在寻找“音量”,而不是“音量”

    此外,反序列化返回的数据不是一个直接的集合,而是一个System.Collections.Dictionary(字符串、对象),其中每个都有一个条目,表示json中的ticker对象

    每个ticker对象包含一个字符串键和一个值,其中值为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()
    

    其中一个问题是,您在testObj中查找的是“Average”,而在JSON中则是“avg”。你也在寻找“音量”,而不是“音量”

    此外,反序列化返回的数据不是一个直接的集合,而是一个System.Collections.Dictionary(字符串、对象),其中每个都有一个条目,表示json中的ticker对象

    每个ticker对象包含一个字符串键和一个值,其中值为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()
    

    可能是区分大小写的问题。我建议用您正在使用的语言标记您的问题。这个问题很可能会得到更多的关注。
    testObj(“ticker”)
    有效吗?我尝试了Dim tickerusdbtc=testObj(“ticker”)并在每一行添加+tickerusdbtc(“high”),但我得到了相同的错误。@skilskilo我已经更新了我的答案并测试了它。我之前犯了一个错误。可能是区分大小写的问题。我建议用您正在使用的语言标记您的问题。这个问题很可能会得到更多的关注。
    testObj(“ticker”)
    有效吗?我尝试了Dim tickerusdbtc=testObj(“ticker”)并在每一行添加+tickerusdbtc(“high”),但我得到了相同的错误。@skilskilo我已经更新了我的答案并测试了它。我之前犯了一个错误。但是我用:Dim avg=testObj(“Average”)@SkiloSkilo声明了avg作为平均值:您所做的只是将一个本地值声明为avg,您没有更改在集合中访问该值的方式。更多信息请参见修改后的答案。像这样吗?输出+=“高:”+cObjects(“高”)+环境。换行输出+=“低:”+cObjects(“低”)+环境。换行输出+=“平均:”+cObjects(“平均值”)+环境。换行输出+=“数量:”+cObjects(“音量”)+环境。换行输出+=“最后一次:”+cObjects(“最后一次”)+环境。换行输出+=“购买:”“+cObjects”(“buy”)+Environment.NewLine out+=”Sell:“+cObjects”(“Sell”)不,那不行。请看修改后的答案。使用stringbuilder来提高效率。但是我用:Dim avg=testObj(“Average”)@SkiloSkilo将avg声明为平均值:您所做的只是将一个本地值声明为avg,您没有更改在集合中访问该值的方式。更多信息请参见修改后的答案。像这样吗?输出+=“高:”+cObjects(“高”)+环境。换行输出+=“低:”+cObjects(“低”)+环境。换行输出+=“平均:”+cObjects(“平均值”)+环境。换行输出+=“数量:”+cObjects(“音量”)+环境。换行输出+=“最后一次:”+cObjects(“最后一次”)+环境。换行输出+=“购买:”“+cObjects”(“buy”)+Environment.NewLine out+=”Sell:“+cObjects”(“Sell”)不,那不行。请看修改后的答案。使用stringbuilder提高效率。