#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.