使用JSon.NET和dynamic数据反序列化JSON

我试图将一些JSON数据反序列化为应用程序的对象。 直到现在,它已经很好,因为在JSON数据的属性是静态的(键值)。 现在我得到了一个关键是dynamic数据的结果。

以下是一个示例JSONurl:

http://en.wikipedia.org/w/api.php?action=query&format=json&pageids=6695&prop=info

由此产生的JSON是:

{ "query" : { "pages" : { "6695" : { "counter" : "", "lastrevid" : 468683764, "length" : 8899, "ns" : 0, "pageid" : 6695, "title" : "Citadel", "touched" : "2012-01-03T19:16:16Z" } } } } 

好吧,除非我不能将“页面”数据反序列化为对象,否则这很好。 如果我要为页面定义一个类,它将看起来像这样:

 public class 6695 { public string counter { get; set; } public int lastrevid { get; set; } public int length { get; set; } public int ns { get; set; } public int pageid { get; set; } public string title { get; set; } public string touched { get; set; } } 

为了反序列化内容(使用JsonConvert.Deserialize(jsondata)),我们都知道我们不能有一个名为6695的类。不仅如此,类的名称将不得不不同(例如pageid = 7145必须是7145级)。

如果我使用诸如JObject.Parse(内容)之类的东西,然后以JArrays的forms访问项目,我似乎可能会挑出一些值,但这很丑陋,我仍然试图从页面数组中获取数据。

寻找人来帮助这一点。 我不认为这是不常见的,这只是我以前遇到的JSON数据,不知道如何处理它。

谢谢!

PS忘了提及这是在Windows Phone 7,所以“dynamic”不可用!

这里是你如何使用https://github.com/facebook-csharp-sdk/simple-json(https://nuget.org/packages/SimpleJson )。

 var text = "{\"query\":{\"pages\":{\"6695\":{\"pageid\":6695,\"ns\":0,\"title\":\"Citadel\",\"touched\":\"2012-01-03T19:16:16Z\",\"lastrevid\":468683764,\"counter\":\"\",\"length\":8899}}}}"; 

(使用dynamic)

 dynamic json = SimpleJson.DeserializeObject(text); string title = json.query.pages["6695"].title; foreach (KeyValuePair<string, dynamic> page in json.query.pages) { var id = page.Key; var pageId = page.Value.pageid; var ns = page.Value.ns; } 

(使用强types的类)

 class result { public query query { get; set; } } class query { public IDictionary<string, page> pages { get; set; } } class page { public long pageid { get; set; } public string title { get; set; } } var result = SimpleJson.DeserializeObject<result>(text); 

[更新]

在Windows Phone不支持dynamic的地方,你不想使用强types的类。

 var json = (IDictionary<string, object>)SimpleJson.DeserializeObject(text); var query = (IDictionary<string, object>)json["query"]; var pages = (IDictionary<string, object>)query["pages"]; var pageKeys = pages.Keys; var page = (IDictionary<string, object>)pages["6695"]; var title = (string)page["title"]; 

最简单的方法。 在这种特殊情况下,可能会变得dynamic

 dynamic data = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json); var lastRevId = data.query.pages["6695"].lastrevid; 

你可以通过它的名字来引用任何元素,这样你就可以做一些类似于data["query"]["pages"]["6695"]["lastrevid"] 。 这将得到所有这些小对象的名称是无效的C#中。

使用Json.net你可以做到:

 Dictionary<string,object> result = JsonConvert.DeserializeObject<Dictionary<string,object>>(json); foreach(var item in result) Console.WriteLine(item.Key + " " + item.Value); 

我希望下面的例子会有所帮助。 我总是devise一个匹配json的模型。 当它是你自己的模型devise时,处理对象要好得多。

从json生成c#模型是非常容易的。 我使用这个网站来生成模型: http : //json2csharp.com

一个完整的例子是:

C#代码:

  var targetsObject = Newtonsoft.Json.JsonConvert.DeserializeObject<YourModel>(jsonString); 

JSON:

  { "investors": [ { "name": "06", "programs": [ { "name": "Conventional", "value": "3.5" }, { "name": "FHA - Standard", "value": "5.0" }, { "name": "FHA - Streamline", "value": "" }, { "name": "VA", "value": "5.5" }, { "name": "VA IRRRL", "value": "6.0" }, { "name": "Non-Prime", "value": "" } ] }, { "name": "07", "programs": [ { "name": "Conventional", "value": "3.5" }, { "name": "FHA - Standard", "value": "5.0" }, { "name": "FHA - Streamline", "value": "7.0" }, { "name": "VA", "value": "5.5" }, { "name": "VA IRRRL", "value": "" }, { "name": "Non-Prime", "value": "" } ] }, { "name": "08", "programs": [ { "name": "Conventional", "value": "3.5" }, { "name": "FHA - Standard", "value": "5.0" }, { "name": "FHA - Streamline", "value": "7.0" }, { "name": "VA", "value": "5.5" }, { "name": "VA IRRRL", "value": "" }, { "name": "Non-Prime", "value": "" } ] }, { "name": "09", "programs": [ { "name": "Conventional", "value": "3.5" }, { "name": "FHA - Standard", "value": "5.0" }, { "name": "FHA - Streamline", "value": "" }, { "name": "VA", "value": "5.5" }, { "name": "VA IRRRL", "value": "" }, { "name": "Non-Prime", "value": "" } ] }, { "name": "10", "programs": [ { "name": "Conventional", "value": "" }, { "name": "FHA - Standard", "value": "" }, { "name": "FHA - Streamline", "value": "" }, { "name": "VA", "value": "" }, { "name": "VA IRRRL", "value": "" }, { "name": "Non-Prime", "value": "2.0" } ] }, { "name": "11", "programs": [ { "name": "Conventional", "value": "3.5" }, { "name": "FHA - Standard", "value": "5.0" }, { "name": "FHA - Streamline", "value": "" }, { "name": "VA", "value": "6.0" }, { "name": "VA IRRRL", "value": "6.0" }, { "name": "Non-Prime", "value": "" } ] }, { "name": "12", "programs": [ { "name": "Conventional", "value": "3.5" }, { "name": "FHA - Standard", "value": "5.0" }, { "name": "FHA - Streamline", "value": "" }, { "name": "VA", "value": "5.5" }, { "name": "VA IRRRL", "value": "6.0" }, { "name": "Non-Prime", "value": "" } ] }, { "name": "13", "programs": [ { "name": "Conventional", "value": "" }, { "name": "FHA - Standard", "value": "5.0" }, { "name": "FHA - Streamline", "value": "" }, { "name": "VA", "value": "" }, { "name": "VA IRRRL", "value": "" }, { "name": "Non-Prime", "value": "2.0" } ] } ] } 

模型:

  public class Program { public string name { get; set; } public string value { get; set; } } public class Investor { public string name { get; set; } public List<Program> programs { get; set; } } public class RootObject { public List<Investor> investors { get; set; } } 

如何在JSONstring中进行简单的search和replace? 虽然它可能不是最优雅的解决scheme,但它可能是最实用的解决scheme。

也许你可以使用一个保留的属性来包含对象types,然后使用本文所示的基types: 使用JSON.NET的dynamictypes