Преобразование Json в List с помощью .NET

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

  1. у вас недопустимая строка 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}
]
}
  
  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; }
}
  
  1. с помощью http://www.newtonsoft.com/json помогите разобрать ваш json

3.1 вот так:

 var jsonObj = JsonConvert.DeserializeObject<RootObject>(jsonString);