Подтвердить что ты не робот

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

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

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

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

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

UPDATE

Я обновил свой вопрос со следующими фрагментами JSON и кодом С#. Я хочу вывести строку "ссылки" на консоль, но она, похоже, не работает. Кажется, я неправильно определяю свои классы?

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"
  }
 ]
}
);

С# фрагмент

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<GoogleSearchResults>(Json);

        Console.WriteLine(results);
        //Console.WriteLine(htmlDoc);
        Console.ReadLine();
    }
}

Спасибо

4b9b3361

Ответ 1

Я использую ваш подход # 2: десериализуем JavaScriptSerializer.

Это то, что я делаю, чтобы десериализовать ответ от Facebook:

// get the id for the uploaded photo
var jss = new JavaScriptSerializer();
var resource = jss.Deserialize<Facebook.Data.Resource>(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, я только десериализую это. Определите поля в своем классе, которые вы хотите десериализовать.

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

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
}

И здесь код С# для десериализации:

    // create a new instance of JavaScriptSerializer
    JavaScriptSerializer s1 = new JavaScriptSerializer();

    // deserialise the received response 
    GoogleSearchResults results = s1.Deserialize<GoogleSearchResults>(json);

    Console.WriteLine(s1.Serialize(results));

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

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

Ответ 2

Вы можете посмотреть Json.NET и LINQ для создания и запроса JSON. Создав хороший запрос LINQ, вы получите только тот материал, который вам нужен (вы можете выбрать, группировать, подсчитывать, мин, макс, что угодно).

Ответ 3

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

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

Вытащите требуемое свойство после преобразования представления JSON в тип приложения С#. Я не думаю, что есть способ извлечь только одно свойство из представления JSON, прежде чем вы его преобразовали (хотя я не уверен).