使用C#反序列化JSON

在尝试在C#中反序列化JSON时,发现在获取信息方面存在一些困难。

我有以JSON格式返回的Google自定义搜索结果。 我只想查看我的步骤并确定顺序以尝试反序列化它。 这是正确的吗?

  1. 我需要创建匹配JSON格式的类。 有点像创建模式文件。
  2. 使用JavaScriptSerializer()类和deserialize方法来提取相关位。

我认为我将遇到的一个问题是我不需要返回所有数据,只需要html链接。 我怎样才能做到这一点?

UPDATE

我已使用以下JSON代码段和C#代码更新了我的问题。 我想将字符串’links’输出到控制台,但它似乎没有工作。 我想我错误地定义了我的课程?

Google自定义搜索中的JSON

 handleResponse({ "kind": "customsearch#search", "url": { "type": "application/json", "template": "https://www.googleapis.com/customsearch/v1?q\u003d{searchTerms}&num\u003d{count?}&start\u003d{startIndex?}&hr\u003d{language?}&safe\u003d{safe?}&cx\u003d{cx?}&cref\u003d{cref?}&sort\u003d{sort?}&alt\u003djson" }, "queries": { "nextPage": [ { "title": "Google Custom Search - lectures", "totalResults": 9590000, "searchTerms": "lectures", "count": 1, "startIndex": 2, "inputEncoding": "utf8", "outputEncoding": "utf8", "cx": "017576662512468239146:omuauf_lfve" } ], "request": [ { "title": "Google Custom Search - lectures", "totalResults": 9590000, "searchTerms": "lectures", "count": 1, "startIndex": 1, "inputEncoding": "utf8", "outputEncoding": "utf8", "cx": "017576662512468239146:omuauf_lfve" } ] }, "context": { "title": "Curriculum", "facets": [ [ { "label": "lectures", "anchor": "Lectures" } ], [ { "label": "assignments", "anchor": "Assignments" } ], [ { "label": "reference", "anchor": "Reference" } ] ] }, "items": [ { "kind": "customsearch#result", "title": "EE364a: Lecture Videos", "htmlTitle": "EE364a: \u003cb\u003eLecture\u003c/b\u003e Videos", "link": "http://www.stanford.edu/class/ee364a/videos.html", "displayLink": "www.stanford.edu", "snippet": "Apr 7, 2010 ... Course materials. Lecture slides · Lecture videos (2008) · Review sessions. Assignments. Homework · Reading. Exams. Final exam ...", "htmlSnippet": "Apr 7, 2010 \u003cb\u003e...\u003c/b\u003e Course materials. \u003cb\u003eLecture\u003c/b\u003e slides · \u003cb\u003eLecture\u003c/b\u003e videos (2008) · Review sessions. \u003cbr\u003e Assignments. Homework · Reading. Exams. Final exam \u003cb\u003e...\u003c/b\u003e", "cacheid": "TxVqFzFZLOsJ" } ] } ); 

C#Snippet

 public class GoogleSearchResults { public string link { get; set; } } public class Program { static void Main(string[] args) { //input search term Console.WriteLine("What is your search query?:"); string searchTerm = Console.ReadLine(); //concantenate the strings using + symbol to make it URL friendly for google string searchTermFormat = searchTerm.Replace(" ", "+"); //create a new instance of Webclient and use DownloadString method from the Webclient class to extract download html WebClient client = new WebClient(); string Json = client.DownloadString("https://www.googleapis.com/customsearch/v1?key=My Key&cx=My CX&q=" + searchTermFormat); //create a new instance of JavaScriptSerializer and deserialise the desired content JavaScriptSerializer js = new JavaScriptSerializer(); GoogleSearchResults results = js.Deserialize(Json); Console.WriteLine(results); //Console.WriteLine(htmlDoc); Console.ReadLine(); } } 

谢谢

我使用#2方法:使用JavaScriptSerializer反序列化。

这就是我对Facebook的响应进行反序列化的方法:

 // get the id for the uploaded photo var jss = new JavaScriptSerializer(); var resource = jss.Deserialize(responseText); 

….其中Facebook.Data.Resource定义如下:

 namespace Facebook.Data { public class Resource { public string id { get; set; } } } 

我反序列化的responseText看起来像这样:

 {"id":"10150111918987952", "from":{"name":"Someone", "id":"782272221"}, "name":"uploaded from Cropper. (at 12\/15\/2010 7:06:41 AM)", "picture":"http:\/\/photos-f.ak.fbcdn.net\/hphotos-ak-snc4\/hs817.snc4\/69790_101501113333332_782377951_7551951_8193638_s.jpg", ... 

但由于我只在Resource类中定义了一个属性,所以我只反序列化 。 定义类中要反序列化的字段。

当然,它可以使用inheritance。 您可以像这样定义数据类:

 namespace Facebook.Data { public class Resource { public string id { get; set; } } public class Person : Resource { public string name { get; set; } } 

}

…然后你可以反序列化Person对象。


编辑

好的,鉴于您在更新的问题中提供的示例json,以下是我如何编写用于保存响应的类:

 public class GoogleSearchItem { public string kind { get; set; } public string title { get; set; } public string link { get; set; } public string displayLink { get; set; } // and so on... add more properties here if you want // to deserialize them } public class SourceUrl { public string type { get; set; } public string template { get; set; } } public class GoogleSearchResults { public string kind { get; set; } public SourceUrl url { get; set; } public GoogleSearchItem[] items { get; set; } // and so on... add more properties here if you want to // deserialize them } 

这是反序列化的C#代码:

  // create a new instance of JavaScriptSerializer JavaScriptSerializer s1 = new JavaScriptSerializer(); // deserialise the received response GoogleSearchResults results = s1.Deserialize(json); Console.WriteLine(s1.Serialize(results)); 

一些评论:

  • 用于保存搜索结果的顶级类称为GoogleSearchResults。
  • GoogleSearchResults类中的第一个属性是kind ,对应于json对象中的第一个命名属性。 您有link不起作用,因为link不是该json对象中顶级属性的名称。 json的层次结构中有一些属性名为“link”,但JavaScriptSerializer不会将这些较低级别的东西拉到更高级别。
  • 我的GoogleSearchResults类中的下一个属性是SourceUrl类型。 这是因为json中的url属性不是一个简单的字符串 – 它是一个带有两个属性的json对象,每个属性都有一个字符串值。 因此,SourceUrl作为C#中的类获取两个字符串属性,每个属性都具有相应的名称以反序列化其中一个命名属性。
  • GoogleSearchResults类中的下一个属性称为“items”,以便它可以从json反序列化项目字典。 现在,顾名思义,项目是json中的一个数组,由围绕其值的方括号表示。 这意味着可以有多个项目,但在您的情况下只有一个项目。 所以C#中的这个属性必须是一个数组(或集合)。 json结果中的每个项目都不是一个简单的字符串,因此,正如我们对SourceUrl所做的那样,我们需要定义一个holder类来反序列化item对象: GoogleSearchItem 。 这个类有一堆简单的字符串属性。 C#类中的属性也可以是int类型或其他类型,如果这是json所需的。
  • 最后,在打印出结果时,如果只调用Console.WriteLine(result)您将看到Console.WriteLine隐式调用的ToString()方法的结果。 这只会打印出类型的名称,在这种情况下是“GoogleSearchResults”,我认为这不是你想要的。 为了查看对象中的内容,您需要对其进行序列化,如我所示。 在输出中,您将只看到反序列化的值的值。 使用我提供的类,结果将比原始类具有更少的信息,因为我没有在C#类中提供与某些json属性相对应的属性,因此没有反序列化。

您可以查看Json.NET及其LINQ支持来创建和查询JSON。 通过制作一个漂亮的LINQ查询,您将只获得所需的东西(您可以选择,分组,计数,分钟,最大,您喜欢的任何内容)。

http://msdn.microsoft.com/en-us/library/bb412170.aspx

http://msdn.microsoft.com/en-us/library/bb410770.aspx

将JSON表示转换为C#应用程序中的类型后,拉出所需的属性。 我认为在转换它之前,有一种方法只能从JSON表示中提取一个属性(虽然我不确定)。