Вопрос или проблема
Доброго времени суток, у нас есть проблема с нашим кодом. Код работает корректно, но затем выдает ошибку, эта ошибка следующая:
Newtonsoft.Json.JsonSerializationException: ‘Не удается десериализовать текущий JSON-объект (например, {“name”:”value”}) в тип ‘System.Collections.Generic.List`1[FlotasNetDAL.CANDataObj]’, потому что этот тип требует JSON-массива (например, [1,2,3]) для корректной десериализации.
Чтобы исправить эту ошибку, либо измените JSON на JSON-массив (например, [1,2,3]), либо измените десериализуемый тип так, чтобы это был обычный .NET тип (например, не примитивный тип, такой как целое число, не коллекция, такая как массив или список), который можно десериализовать из JSON-объекта. Также можно добавить JsonObjectAttribute к типу, чтобы заставить его десериализоваться из JSON-объекта.
Путь ‘[0].CANInfo.CANData’, строка 1, позиция 301.’
Вот наши классы:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlotasNetDAL
{
public class vehicleInfo
{
public long uniqueID { get; set; }
public string? plate { get; set; }
public DateTime GPSDate { get; set; }
public float latitude { get; set; }
public float longitude { get; set; }
public int speed { get; set; }
public int course { get; set; }
public float odometer { get; set; }
public DateTime receivedDate { get; set; }
public stateDataList? stateInfo { get; set; }
public int GPSQuality { get; set; }
public List<CANDataObj>? CANInfo { get; set; }
public peripheralsDataList? peripheralsInfo { get; set; }
public geofenceData? geofenceInfo { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlotasNetDAL
{
public class CANDataObj
{
public string? CANParam { get; set; }
public string? CANValue { get; set; }
}
}
Мы пытались изменить эту строку
public List<CANDataObj>? CANInfo { get; set; }
на
public CANDataObj? CANInfo { get; set; }
Начали получать данные, но ошибка продолжает появляться.
Спасибо, если сможете помочь мне
Ответ или решение
Добрый день!
Вы столкнулись с ошибкой десериализации JSON, и из сообщения об ошибке можно понять, что проблема заключается в ожидаемом формате входных данных. Давайте проанализируем ваш код и предоставим рекомендации для исправления ошибки.
Ошибка
Ошибка, которую вы получаете:
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[FlotasNetDAL.CANDataObj]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
указывает на то, что в процессе десериализации вы ожидаете массив объектов CANDataObj
, но получаете объект. Это означает, что JSON, который вы получаете от API, не соответствует ожидаемому формату.
Проверка JSON
Прежде всего, вам нужно проверить формат JSON, который вы получаете с API. Вот пример того, что вы могли бы ожидать при правильной конфигурации:
{
"uniqueID": 1,
"plate": "ABC123",
"GPSDate": "2023-10-01T12:00:00",
"latitude": 50.0,
"longitude": 8.0,
"speed": 60,
"course": 90,
"odometer": 15000.5,
"receivedDate": "2023-10-01T12:00:01",
"GPSQuality": 1,
"CANInfo": [
{
"CANParam": "Parameter1",
"CANValue": "Value1"
},
{
"CANParam": "Parameter2",
"CANValue": "Value2"
}
],
"peripheralsInfo": null,
"geofenceInfo": null
}
Исправление модели
Теперь, если ваш JSON имеет вид, как указано выше, то ваша текущая модель vehicleInfo
должна выглядеть правильно. Основная проблема, скорее всего, заключается в том, что в JSON, который вы получаете, поле CANInfo
не является массивом, а объектом. Например:
{
"CANInfo": {
"CANParam": "Parameter1",
"CANValue": "Value1"
}
}
Если ваше API действительно возвращает объект вместо массива, то вам нужно изменить тип поля CANInfo
обратно на CANDataObj?
(одиночный экземпляр объекта) и соответствующим образом настроить использование в коде.
Пример исправленной модели
public class vehicleInfo
{
public long uniqueID { get; set; }
public string? plate { get; set; }
public DateTime GPSDate { get; set; }
public float latitude { get; set; }
public float longitude { get; set; }
public int speed { get; set; }
public int course { get; set; }
public float odometer { get; set; }
public DateTime receivedDate { get; set; }
public stateDataList? stateInfo { get; set; }
public int GPSQuality { get; set; }
public CANDataObj? CANInfo { get; set; } // Меняем снова на одиночный объект
public peripheralsDataList? peripheralsInfo { get; set; }
public geofenceData? geofenceInfo { get; set; }
}
Проверка поля CANInfo
Если API может со временем возвращать либо массив, либо объект, рекомендуется создать кастомный десериализатор, который будет обрабатывать оба случая.
Заключение
Итак, если API возвращает объект в поле CANInfo
, убедитесь, что модель соответствует этому формату. Если API может возвращать как массив, так и объект, будет лучше создать метод для десериализации, который сможет обрабатывать оба случая.
Если у вас остались дополнительные вопросы или вам нужна помощь с кодом десериализатора, пожалуйста, не стесняйтесь задать вопрос. Удачи вам с вашим проектом!