Deserializing JSON с использованием C #

Нахождение некоторых трудностей в поиске информации при попытке десериализации JSON в C #.

У меня есть результаты пользовательского поиска Google, возвращенного в формате JSON. Я просто хочу проверить свои шаги и установить порядок в попытке десериализации. Это правильно?

  1. Мне нужно создать classы для соответствия формату JSON. Это похоже на создание файла схемы.
  2. Используйте class JavaScriptSerializer() и метод deserialize для извлечения соответствующих битов.

Одна из проблем, которые, как мне кажется, я собираюсь запутать, заключается в том, что мне не требуются все возвращенные данные, а только ссылки html. Как я могу это достичь?

ОБНОВИТЬ

Я обновил свой вопрос со следующими fragmentами JSON и кодом C #. Я хочу вывести строку «ссылки» на консоль, но она, похоже, не работает. Кажется, я неправильно определяю свои classы?

JSON из Google Custom Search

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

Но поскольку у меня есть только одно свойство, определенное в classе Resource , я только десериализую это . Определите поля в своем classе, которые вы хотите десериализовать.

Разумеется, он работает на наследование. Вы можете определить свои classы данных следующим образом:

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

}

… и затем вы можете десериализовать объект Person .


РЕДАКТИРОВАТЬ

Хорошо, учитывая пример json, который вы указали в обновленном вопросе, вот как я написал classы для ответа:

 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)); 

Некоторые комментарии:

  • Класс toplevel для хранения результатов поиска называется GoogleSearchResults.
  • Первое свойство в classе GoogleSearchResults является kind , что соответствует первому именованному свойству в объекте json. У вас была link которая не будет работать, потому что link не является именем свойства верхнего уровня в этом объекте json. Есть свойства ниже в иерархии вашего json с именем «link», но JavaScriptSerializer не вытащит эти вещи более низкого уровня на более высокий уровень.
  • Следующее свойство в моем classе GoogleSearchResults имеет тип SourceUrl. Это связано с тем, что свойство url в json не является простой строкой – это json-объект с двумя свойствами, каждый со строковым значением. Таким образом, SourceUrl как class в C # получает два свойства строки, каждый из которых имеет соответствующее имя для десериализации одного из этих именованных свойств.
  • следующее свойство в classе GoogleSearchResults называется «items», так что оно может десериализовать словарь предметов из вашего json. Теперь элементы, как следует из названия, представляют собой массив в json, который обозначается квадратной скобкой вокруг его значения. Это означает, что может быть более одного элемента, хотя в вашем случае есть только один элемент. Таким образом, это свойство в C # должно быть массивом (или набором). Каждый элемент в json-результате не является простой строкой, поэтому, как и в случае с SourceUrl, нам нужно определить class-держатель для десериализации объекта item: GoogleSearchItem . Этот class имеет кучу простых строковых свойств. Свойства в classе C # также могут иметь тип int или какой-либо другой тип, если это то, что требует json.
  • наконец, при распечатке результата, если вы просто вызываете Console.WriteLine(result) вы увидите результат метода ToString() который неявно вызывается Console.WriteLine . Это просто напечатает имя типа, в данном случае это «GoogleSearchResults», который, как мне кажется, не является тем, что вы хотите. Чтобы увидеть, что находится в объекте, вам нужно сериализовать его, как я показал. В результате этого вы увидите только значения тех вещей, которые вы десериализировали . Используя предоставленные мной classы, результат будет иметь меньше информации, чем оригинал, потому что я не предоставил свойства в classе 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, прежде чем вы его преобразовали (хотя я не уверен).