На данный вопрос уже ответили:
Есть такой JSON (так-то он длиннее):
{
"result": [
[
9069250,
"2018-07-05 23:22:33",
"2018-07-20 12:33:26"
],
[
501184,
"2018-07-07 07:25:57",
"2018-07-20 12:33:31"
],
[
9117,
"2018-07-07 21:11:30",
"2018-07-20 12:42:57"
],
[
10539675,
"2018-07-07 21:17:14",
"2018-07-19 10:17:25"
]
]
}
Пытаюсь его десериализовать, но безуспешно... Не знаю как описать класс для такого json(a), потому что обычно пишут "атрибут:значение", а здесь просто каждый элемент это 3 перечисленных значения и вот как это всё мне по переменным раскидать...
Пробовал такой класс:
class JSON
{
public result[] result { get; set; }
}
class result
{
public string domain_id { get; set; }
public string start { get; set; }
public string stop { get; set; }
}
Но не получилось...
Код, который использую для сериализации:
StreamReader re = new StreamReader("JSON.json");
JsonTextReader reader = new JsonTextReader(re);
JsonSerializer se = new JsonSerializer();
var DeserializedObject = se.Deserialize<JSON>(reader);
При запуске, у меня вышла ошибка:
"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'ConsoleApp1.Program+result' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path 'result[0]', line 3, position 9."
Решить которую так и не удалось...
Предлагаю сначала разобрать в массив массивов строк
public class Data
{
public List<List<string>> Result;
}
var data = JsonConvert.DeserializeObject<Data>(youJson);
Далее способ подходит в случае если ты 100% уверен, что порядок строк не поменяется. Создаем атрибут, который поможет нам упорядочить порядок пропертей в классе для извлечения их через рефлексию.
public class IndexAttribute : Attribute
{
public int Order { get; }
public IndexAttribute(int order)
{
Order = order;
}
}
Далее сам класс с нужными пропертями и уже навешанными атрибутами. Где цифра это их порядок в десереализуемом массиве.
public class Info
{
[Index(0)]
[JsonProperty("domain_id")]
public string DomainId { get; set; }
[Index(1)]
public string Start { get; set; }
[Index(2)]
public string Stop { get; set; }
}
Ну и сам код разбора в объект. Код на неискушенный взгляд может показаться сложным и не избыточным, но мне нравятся LINQ. Можно было бы и через обычные for это сделать.
var infoProps = typeof(Info).GetProperties().OrderBy(p => p.GetCustomAttribute<IndexAttribute>().Order).ToList();
var result = b.Result.Select(rawInfo => infoProps.Zip(rawInfo, (prop, s) => new {prop, s}).Aggregate(new Info(),
(instance, pair) =>
{
pair.prop.SetValue(instance, pair.s);
return instance;
})).ToList();
Суть проста. Сначала через рефлексию достаю все проперти и сортирую их по убыванию.
Далее для каждого элемента массива "result" склеиваю их в пары (проперти - значение) и через метод Aggregate создаю экземпляры класса Info и в нем же заполняю все его свойства.
Такой способ бывает необходимо, когда нужно разобрать данные в упорядоченном виде без наименования поля.
Оказывается в студии есть встроенный инструмент для перевода json в классы: Edit -> Paste special -> Paste JSON as classes, который решил все мои проблемы
Сборка персонального компьютера от Artline: умный выбор для современных пользователей