使用Json.NET来反序列化此类数据

本文关键字:数据 反序列化 Json NET 使用 | 更新日期: 2023-09-27 18:25:34

我正在为Omegle写一些东西,我得到的响应是:

{ "clientID" : "shard2:jgv1dnwhyffmld7kir5drlcwp7k6eu",
  "events" : [ [ "waiting" ],
      [ "statusInfo",
        { "antinudepercent" : 1.0,
          "antinudeservers" : [ "waw1.omegle.com",
              "waw2.omegle.com",
              "waw3.omegle.com"
            ],
          "count" : 28477,
          "servers" : [ "front1.omegle.com",
              "front8.omegle.com",
              "front7.omegle.com",
              "front9.omegle.com",
              "front2.omegle.com",
              "front5.omegle.com",
              "front3.omegle.com",
              "front6.omegle.com",
              "front4.omegle.com"
            ],
          "spyQueueTime" : 0.000099992752075199996,
          "spyeeQueueTime" : 0.8086000442504,
          "timestamp" : 1375197484.3550739
        }
      ]
    ]
}

为了将这些数据放入字典,我尝试使用以下函数:

    private Dictionary<string, object> deserializeToDictionary(string jo)
    {
        Dictionary<string, object> values = JsonConvert.DeserializeObject<Dictionary<string, object>>(jo);
        Dictionary<string, object> values2 = new Dictionary<string, object>();
        foreach (KeyValuePair<string, object> d in values)
        {
            if (d.Value.GetType().FullName.Contains("Newtonsoft.Json.Linq.JObject"))
            {
                values2.Add(d.Key, deserializeToDictionary(d.Value.ToString()));
            }
            else
            {
                values2.Add(d.Key, d.Value);
            }
        }
        return values2;
    }

然而,我得到以下错误:

无法将当前JSON数组(例如[1,2,3])反序列化为类型'System.Collections.Generic.DDictionary2[System.String,System.Object]'因为该类型需要一个JSON对象(例如{"name":"value"})正确反序列化。

要修复此错误,请将JSON更改为JSON对象(例如。{"name":"value"})或将反序列化类型更改为数组或实现集合接口的类型(例如ICollection、IList)比如可以从JSON数组反序列化的List。JsonArrayAttribute也可以添加到类型中,以强制它从JSON数组反序列化。

我做错了什么?

使用Json.NET来反序列化此类数据

您的问题"我为什么会出现这个错误"的简短答案是,您的JSON是JSON对象和数组的混合体,但您的代码似乎试图将所有内容反序列化到字典中。Json.Net无法将数组反序列化为字典,因此它抛出了此错误。反序列化时,必须确保将JSON对象与.NET对象(或Dictionaries)匹配,将JSON数组与.NET数组(或Lists)匹配。

那么,我们如何让事情运转起来呢?好吧,如果你只想要一个可以处理任意JSON并将其转换为常规.NET类型(原语、列表和字典)的泛型函数,那么你可以使用JSON.NET的Linq-to-JSON API来做这样的事情:

private static object Deserialize(string json)
{
    return ToObject(JToken.Parse(json));
}
private static object ToObject(JToken token)
{
    if (token.Type == JTokenType.Object)
    {
        Dictionary<string, object> dict = new Dictionary<string, object>();
        foreach (JProperty prop in ((JObject)token).Properties())
        {
            dict.Add(prop.Name, ToObject(prop.Value));
        }
        return dict;
    }
    else if (token.Type == JTokenType.Array)
    {
        List<object> list = new List<object>();
        foreach (JToken value in token.Values())
        {
            list.Add(ToObject(value));
        }
        return list;
    }
    else
    {
        return ((JValue)token).Value;
    }
}

另一方面,当您可以将所有内容都保留为JObjects和JArrays,并使用API直接查找您要查找的内容时,为什么还要麻烦呢?例如,如果你想获得所有的事件名称,你可以这样做:

var events = JObject.Parse(json)["events"];
var eventNames = events.Select(a => a[0].Value<string>()).ToList();

如果你想获得所有"gotMessage"事件的所有消息,你可以做:

var messages = events.Where(a => a[0].Value<string>() == "gotMessage")
                     .Select(a => a[1].Value<string>())
                     .ToList();

Discalimer:我对"Omegle"或其API一点也不熟悉,所以我只是根据您的问题和评论猜测JSON的格式是什么。我也不知道你到底对什么数据感兴趣,所以你几乎肯定需要做出调整来满足你的需求。希望这些例子足以让你"摆脱困境"。我还建议查看文档中的Linq-to-JSON示例。