Получение исключения при попытке десериализации JSON и отображения результатов в DataGridView

#c# #json #datagridview #json.net

#c# #json #datagridview #json.net

Вопрос:

У меня есть некоторый код на C #, в котором я получаю данные JSON из API. JSON выглядит следующим образом:

 {
    "count": 32696,
    "results": [{
        "data_id": 0,
        "name": "Extended Potion of Ghost Slaying",
        "rarity": 0,
        "restriction_level": 0,
        "img": "",
        "type_id": 0,
        "sub_type_id": 0,
        "price_last_changed": "2013-03-18 17:00:31 UTC",
        "max_offer_unit_price": 0,
        "min_sale_unit_price": 0,
        "offer_availability": 0,
        "sale_availability": 0,
        "sale_price_change_last_hour": 0,
        "offer_price_change_last_hour": 0
    }]
}
  

(Хотя в результатах больше, чем один элемент.)

Я создал 2 таких класса:

 internal class MyClass
{
    public int data_id { get; set; }
    public string name { get; set; }
    public int rarity { get; set; }
    public int restriction_level { get; set; }
    public string img { get; set; }
    public int type_id { get; set; }
    public int sub_type_id { get; set; }
    public string price_last_changed { get; set; }
    public int max_offer_unit_price { get; set; }
    public int min_sale_unit_price { get; set; }
    public int offer_availability { get; set; }
    public int sale_availability { get; set; }
    public int sale_price_change_last_hour { get; set; }
    public int offer_price_change_last_hour { get; set; }
}

internal class RootObject
{
    public int count { get; set; }
    public List<MyClass> results { get; set; }
}
  

И вот та часть, где я получаю JSON и десериализую его:

 using (WebClient wc = new WebClient())
{
    string URI = "a good url";

    wc.Headers.Add("Content-Type", "text");
    string HtmlResult = wc.DownloadString(URI);
    MyClass[] result = JsonConvert.DeserializeObject<MyClass[]>(HtmlResult);
    DataTable dt = (DataTable)JsonConvert.DeserializeObject(HtmlResult, (typeof(DataTable)));
    this.dataGridView1.DataSource = dt;
}
  

Но когда я запускаю этот код, я получаю сообщение об ошибке:

Дополнительная информация: Не удается десериализовать текущий объект JSON (например, {«name»:»value»}) в тип ‘gwspiderv2.MyClass[]’, поскольку для правильной десериализации требуется массив JSON (например, [1,2,3] ) .

Я уже использую этот тип кода в другом API без ошибок. Что я делаю не так?

Комментарии:

1. Да, у вас есть JSON для одного (1) объекта, сам по себе, а не в массиве, просто сидит там с фигурными скобками. Оно заключено в квадратные скобки? Нет. Это не так. В JSON массив представляет собой последовательность объектов или значений, разделенных запятыми, в квадратных скобках. Вы говорите десериализатору десериализовать массив — вы говорите ему настаивать на массиве. Таким образом, он ищет массив. Вместо этого он находит то, что вы ему дали. Итак, он говорит: «это не массив».

2. Как выглядит ваш необработанный JSON? Исходя из ошибки, это должен быть объект JSON, а не массив. Может быть, вы хотели десериализовать JSON до того RootObject типа, который вы не используете?

3. json выглядит следующим образом: {«count»:32696,»results»:[{«data_id»:0, «name»: «Расширенное зелье убийства призраков», «редкость»:0, «restriction_level»: 0, «img»:»»,»type_id»:0,»sub_type_id»:0,»price_last_changed»: «2013-03-18 17:00:31 UTC»,»max_offer_unit_price»:0,»min_sale_unit_price»:0,»offer_availability»:0,»sale_availability»:0,»sale_price_change_last_hour»:0,»offer_price_change_last_hour»:0},{«data_id»:1,»name»:»МОНСТР ТОЛЬКО Моа безоружный * и так далее

Ответ №1:

В вашем коде кажется, что вы пытаетесь десериализовать один и тот же JSON двумя разными способами, что не имеет большого смысла:

 MyClass[] result = JsonConvert.DeserializeObject<MyClass[]>(HtmlResult);
DataTable dt = (DataTable)JsonConvert.DeserializeObject(HtmlResult, (typeof(DataTable)));
  

Вы получаете первую ошибку (в вашем вопросе), потому что ваш JSON представляет один объект, но вы пытаетесь десериализовать его в массив MyClass . Вы определили RootObject класс, но вы его не используете. Кажется, что так и должно быть, потому что это соответствует вашему JSON.

Вы получаете вторую ошибку (в комментариях к ответу @inan), потому что JSON находится в неправильном формате для десериализации в a DataTable . Предположительно, вы пытаетесь сделать это, чтобы вы могли отображать данные в своем DataGridView . Но вам не нужно преобразовывать его в a DataTable , чтобы использовать его в качестве источника данных. Вы можете просто указать свой DataGridView an IList , который у вас уже есть в вашем RootObject .

Измените свой код на это:

 RootObject result = JsonConvert.DeserializeObject<RootObject>(HtmlResult);
this.dataGridView1.DataSource = result.results;
  

Ответ №2:

Используйте RootObject для десериализации, как показано ниже, у него есть список MyClass

 RootObject result = JsonConvert.DeserializeObject<RootObject>(HtmlResult);
  

Комментарии:

1. получить эту ошибку: Дополнительная информация: неожиданный токен JSON при чтении DataTable. Ожидаемый StartArray, получил StartObject . Путь «, строка 1, позиция 1.