Проблема с десериализацией JSON (получен массив значений, когда ожидается одно значение)

Я читаю данные из базы данных графа и получаю ответ в виде динамического объекта. Я просматриваю результаты и пытаюсь десериализовать их так:

var e = results.GetEnumerator();

while (e.MoveNext())
{
    var serialized = JsonConvert.SerializeObject(e.Current);
    // {"FlagCalculateclientside":[false],"Description":["Some detailed info"], "Name": ["MyDetailedEntity"]}
    var val = JsonConvert.DeserializeObject<MyObject>(serialized);
}

public class MyObject
{
    public bool FlagCalculateclientside { get; set; }
    public string Description { get; set; }
    public string Name { get; set; }
}

Но я получаю следующую ошибку:

Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: [. Path 'FlagCalculateclientside', line 1, position 28. at Newtonsoft.Json.JsonTextReader.ReadAsBoolean() at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter) ...

Я предполагаю, что это потому, что значения находятся в массивах, но ожидалось только одно значение для каждого ключа.

Есть идеи, как это исправить?

Код с комментариями в вопросе - это ваш ответ json?

A.M. Patel 30.05.2019 12:57

Откуда берутся результаты? Как устроены эти данные/объект?

Tony Abrams 30.05.2019 12:58

@ЯВЛЯЮСЬ. Патель Да, это значение "сериализованный"

kanpeki 30.05.2019 12:58

@Tony Abrams Я делаю запрос клиенту Gremlin, например: var results = await gremlinClient.SubmitAsync<dynamic>(requestScript).ConfigureA‌​wait(false); requestScript просто содержит мою строку запроса Gremlin

kanpeki 30.05.2019 13:01

Как выглядит запрос Gremlin?

Tony Abrams 30.05.2019 13:04
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
613
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваша модель не соответствует вашему JSON, все свойства являются массивами, другими словами, они окружены [...]. Чтобы исправить, измените модель на эту:

public class MyObject
{
    public List<bool> FlagCalculateclientside { get; set; }
    public List<string> Description { get; set; }
    public List<string> Name { get; set; }
}

Альтернативой может быть использование пользовательского конвертера, например:

public class ArrayConverter<T> : JsonConverter<T>
{
    public override T ReadJson(JsonReader reader, Type objectType, T existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        JToken token = JToken.Load(reader);

        //This isn't the best code but shows you what you need to do.
        return token.ToObject<List<T>>().First();
    }

    public override void WriteJson(JsonWriter writer, T value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

И измените свою модель на это:

public class MyObject
{
    [JsonConverter(typeof(ArrayConverter<bool>))]
    public bool FlagCalculateclientside { get; set; }

    [JsonConverter(typeof(ArrayConverter<string>))]
    public string Description { get; set; }

    [JsonConverter(typeof(ArrayConverter<string>))]
    public string Name { get; set; }
}

Хотя это «исправляет» проблему, не имеет смысла заставлять модель иметь массивы, поскольку OP заявляет, что они ожидают только одно значение для каждого поля в модели.

Tony Abrams 30.05.2019 13:03

@TonyAbrams OP спросил, как решить проблему, и это сделало это. Альтернативой является исправление запроса Gremlin, но это довольно сложно сделать. Обычно Gremlin предоставляет вам значения свойств в виде массивов.

DavidG 30.05.2019 13:04

Спасибо за ответ. Я надеюсь, что смогу сопоставить первое свойство в каждом массиве со свойством в моей модели. В этих массивах никогда не будет более одного элемента, просто ответ такой...

kanpeki 30.05.2019 13:07

@kanpeki Ну, это означает, что вам нужно изменить свой запрос, который является совершенно другим вопросом.

DavidG 30.05.2019 13:09

@DavidG Я не очень хорошо с этим знаком, но нет ли способа создать собственный десериализатор?

kanpeki 30.05.2019 13:12

@kanpeki Хорошо, я добавил пример использования пользовательского конвертера.

DavidG 30.05.2019 13:25

Другие вопросы по теме