2013-07-30 46 views
1

我正在寫東西Omegle的,而這是一種反應,我得到:使用Json.NET反序列化這種數據

{ "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.

我在做什麼錯?

+0

這裏你的總體目標是什麼?您是否真的需要將信息嵌入到一系列嵌套字典中,或者您是否試圖將其轉化爲易於使用的類結構?你需要所有的信息還是隻是其中的一部分?這將有助於回答你的問題。 –

+0

我並不需要所有的數據。我目前所做的只是使用IndexOf和Substring來過濾掉所有我不需要的東西,但是當數據與平時稍有不同時會導致錯誤。我一般只需要一些東西,比如'[[「typing」],[「gotMessage」,「Hello!」],[「stoppedTyping」],'' –

回答

4

對於你的問題「爲什麼我得到這個錯誤」的簡短答案是你的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