c# - 使用 Json.NET 反序列化这种数据

标签 c# json serialization json.net

我正在为 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;
    }

但是,我收到以下错误:

Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Collections.Generic.Dictionary2[System.String,System.Object]' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.

To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.

我做错了什么?

最佳答案

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

那么,我们如何让事情正常进行呢?好吧,如果您只想要一个可以处理任意 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 samples在文档中。

关于c# - 使用 Json.NET 反序列化这种数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17951145/

相关文章:

javascript - jQuery 嵌套 $(this) 在完整函数内失败

c# - 如何将自定义 WebViewPage 属性从 View 传递到布局?

c# - 对象到字节数组到字符串并返回

c# - c# sealed 和 Java 的 final 关键字之间有什么功能上的区别吗?

json - 检查 Instagram 帐户是公共(public)帐户还是私有(private)帐户

asp.net-mvc - 返回对象名称为 MVC 的 Json 结果

c# - 反序列化时传入对象引用

c# - StringContent 与 ObjectContent

c++ - 如何将 C++ 对象保存到 xml 文件中并恢复?

c# - 在 Visual Studio (C#) 中的编译时设置值?