#c# #.net #json
#c# #.net #json
Вопрос:
После нескольких дней попыток преобразовать Json в список объектов я здесь. У меня есть REST API, который возвращает строку Json:
{
GetItemsListResult:"[
{
"code":"VOL00056",
"clsID":223108653,
"type":2,
"status":1,
"free":0.0,
"total":671088640.0,
"perc":99,
"descr":"no mailing",
"dt":20160926,
"tm":112456,
"full":1
},
{
"code":"VOL00055",
"clsID":111760419,
"type":2,
"status":1,
"free":0.0,
"total":671088640.0,
"perc":99,
"descr":"Email",
"dt":20160817,
"tm":222411,
"full":1
}
]"
}
Я знаю, что эта строка взята из DataTable:
String JSONresult = JsonConvert.SerializeObject(ds.Tables[0]);
Я создал два класса: один, который описывает объектную модель, а другой, который получает коллекцию. Но при попытке
VolumeCollection volumes = Newtonsoft.Json.JsonConvert.DeserializeObject<VolumeCollection>(listVolumes);
Я получаю
Не удалось выполнить приведение или преобразование из системы.Строка в систему.Коллекции.Generic.List`1[Объем].
Что не так?
Класс тома:
public class Volume
{
public String code { get; set; }
public Int32 classId { get; set; }
public Byte volumeType { get; set; }
public Byte status { get; set; }
public float freeSpace { get; set; }
public float totalSpace { get; set; }
public Int16 fillPercentage { get; set; }
public String classDescription { get; set; }
public Int32 closeDate { get; set; }
public Int32 closeTime { get; set; }
public Boolean isFull { get; set; }
}
Полученная строка json:
«»
[{\»FreeSpace\»:0.0,\»TotalSpace\»:671088640.0,\»FillPercentage\»:99,\»ClassDescription\»:\» Электронная почта esterne\»,\»Дата закрытия \»:20161001,\»CloseTime\»:212512,\»IsFull\»:true,\»VolumeType\»:2,\»ClassId\»:111760419,\»Code\»:\»VOL00057\»,\»Status\»:1},
{\» Свободное пространство \»: 0.0,\»TotalSpace \»:671088640.0,\»FillPercentage \»:99,\»ClassDescription \»:\»Корреспонденции нет»,\»Закрытая дата \»:20160926,\»CloseTime\»:112456,\»IsFull\»:true,\»VolumeType\»:2,\»ClassId\»:223108653,\»Code\»:\»VOL00056\»,\»Статус\»:1}
]»»
Кажется, это недопустимый json…
Комментарии:
1. Можете ли вы поделиться своим
VolumeCollection
классом?2. общедоступный класс VolumeCollection { общедоступный список<Объем> GetItemsListResult { получить; установить; } }
3. у вас недопустимая строка json
4. Не могли бы вы
Volume
тоже поделиться классом? Желательно добавить это в свой вопрос. А такжеVolumeCollection
класс.5. Ваша строка JSON недопустима. Вот почему он не может десериализоваться. Можете ли вы опубликовать контроллер, генерирующий этот JSON? Что-то не так с этой частью.
Ответ №1:
Учитывая, что ваш json
неверен, и учитывая, что следующее:
{
"GetItemsListResult": [{
"code": "VOL00056",
"clsID": 223108653,
"type": 2,
"status": 1,
"free": 0.0,
"total": 671088640.0,
"perc": 99,
"descr": "no mailing",
"dt": 20160926,
"tm": 112456,
"full": 1
}, {
"code": "VOL00055",
"clsID": 111760419,
"type": 2,
"status": 1,
"free": 0.0,
"total": 671088640.0,
"perc": 99,
"descr": "Email",
"dt": 20160817,
"tm": 222411,
"full": 1
}]
}
используя следующие классы, которые я сгенерировал, это работает:
public class GetItemsListResult
{
public string code { get; set; }
public int clsID { get; set; }
public int type { get; set; }
public int status { get; set; }
public double free { get; set; }
public double total { get; set; }
public int perc { get; set; }
public string descr { get; set; }
public int dt { get; set; }
public int tm { get; set; }
public int full { get; set; }
}
public class RootObject
{
public List<GetItemsListResult> GetItemsListResult { get; set; }
}
var res = JsonConvert.DeserializeObject<RootObject>(json);
Примечание: этот сайт сгенерировал классы из JSON
: json2csharp
Комментарии:
1. Хорошо, учитывая, что json поступает из DataTable, могу ли я его изменить? Могу ли я переименовать GetItemsListResult со значением имени?
2. Не уверен, что я вас понимаю, вы хотите сказать, что вы не контролируете, как создается json?
3. Более или менее… Я могу «убедить» тех, кто готовит json 🙂 Данные поступают из таблицы базы данных. Как я могу изменить подготовку данных?
4. Вместо того, чтобы просто использовать DataTable в первую очередь, создавайте объекты из каждой строки таблицы, а затем сериализуйте их
json
вместо этого, это гораздо удобнее в обслуживании.5. Хорошо, вместо DataTable выполните цикл с помощью DataReader и создайте список объектов. Верно?
Ответ №2:
GetItemsListResult
Это строка, а не массив. Обратите внимание на двойные кавычки:
GetItemsListResult: "[
Итак, в идеале вы хотите сделать свой json реальным массивом.
Если у вас нет контроля над json, то в качестве плохой альтернативы вы можете рекурсивно проанализировать строки для извлечения массива.
Ответ №3:
- у вас недопустимая строка json:
1.1 допустимый json, подобный этому:
{
"GetItemsListResult":[
{"code":"VOL00056","clsID":223108653,"type":2,"status":1,"free":0.0,"total":671088640.0,"perc":99,"descr":"no mailing","dt":20160926,"tm":112456,"full":1},
{"code":"VOL00055","clsID":111760419,"type":2,"status":1,"free":0.0,"total":671088640.0,"perc":99,"descr":"Email","dt":20160817,"tm":222411,"full":1}
]
}
- С помощью http://json2csharp.com / построить модель данных
2.1 вот так:
public class GetItemsListResult
{
public string code { get; set; }
public int clsID { get; set; }
public int type { get; set; }
public int status { get; set; }
public double free { get; set; }
public double total { get; set; }
public int perc { get; set; }
public string descr { get; set; }
public int dt { get; set; }
public int tm { get; set; }
public int full { get; set; }
}
public class RootObject
{
public List<GetItemsListResult> GetItemsListResult { get; set; }
}
- с помощью http://www.newtonsoft.com/json помогите разобрать ваш json
3.1 вот так:
var jsonObj = JsonConvert.DeserializeObject<RootObject>(jsonString);