Задать вопрос
NikFaraday
@NikFaraday
Student full-stack Developer

Почему не десериализуется JSON объект при помощи Newtonsoft.Json?

Здравствуйте!

Не могу показывать полный объект, покажи лишь проблему в частях. Тестирую код на сериализацию/десериализацию. При сериализации объект нормально записывается, тут проблем нету При десериализации возникает ошибка:

Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing value: {. Path 'Header.CoverPage.Title', line 12, position 16.'


Как на самом деле выглядит это место в файле:
65df4ef268d9b224168188.png
Простите, что всё зачеркнуто и жмёт глаз, по другому не могу

Самое интересно, что если закидывать эту json-ку в онлайн-форматтеры, то всё нормально, весь объект показывает целиком и в нормальном виде, без ошибок. Для десериализации использую Newtonsoft.Json, вот упрощённый пример кода для десериализации:

string readJsonObject = string.Empty;

using (StreamReader sr = new StreamReader(path))
{
    readJsonObject += sr.ReadToEnd();
}
MyType JsonConvert.DeserializeObject<MyType>(readJsonObject);
  • Вопрос задан
  • 322 просмотра
Подписаться 1 Средний 7 комментариев
Решения вопроса 1
NikFaraday
@NikFaraday Автор вопроса
Student full-stack Developer
Сделаю заключение долгих попыток десериализации сложных объектов, советов и рекомендаций.

Первое что нужно понимать при сериализации и десериализации, что объект должен иметь возможность полного построения, т.е., иметь public конструктор и все свойства должны быть set (Именно public set, init так же не подходит)

Проблема в том, что сериализаторы (По крайней мере те, который я использовал, это Newtonsoft.Json, System.Json и Utf8Json) не работают с System.Reflection, т.е., они могут восстановить только те поля/свойства, который доступны публично

BinarySerialization так же не подходит

Почему я не встречал такой ошибки раньше? Потому что на проектах типу web api + react основной единицей транспортировки данных были модели, так называемые DTO (Data Transfer Object), которые сами по себе имеют только публичные свойства и стандартный публичный конструктор без параметров и эти объекты отлично работают для отправки информации через http
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
VoidVolker
@VoidVolker Куратор тега C#
Dark side eye. А у нас печеньки! А у вас?
Попробуйте сделать парсер через quicktype (Как правильно описать класс для библиотеки Newtonsoft.Json C#?) - похоже, что где-то у вас несоответствие типа и JSON.
spoiler
{
  "Header": {
    "CoverPage": {
        "Title": { "Content": "data" }
    }
  }
}

// <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
//    using QuickType;
//
//    var data = Data.FromJson(jsonString);

namespace QuickType
{
    using System;
    using System.Collections.Generic;

    using System.Globalization;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Converters;

    public partial class Data
    {
        [JsonProperty("Header")]
        public Header Header { get; set; }
    }

    public partial class Header
    {
        [JsonProperty("CoverPage")]
        public CoverPage CoverPage { get; set; }
    }

    public partial class CoverPage
    {
        [JsonProperty("Title")]
        public Title Title { get; set; }
    }

    public partial class Title
    {
        [JsonProperty("Content")]
        public string Content { get; set; }
    }

    public partial class Data
    {
        public static Data FromJson(string json) => JsonConvert.DeserializeObject<Data>(json, QuickType.Converter.Settings);
    }

    public static class Serialize
    {
        public static string ToJson(this Data self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
    }

    internal static class Converter
    {
        public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
        {
            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
            DateParseHandling = DateParseHandling.None,
            Converters =
            {
                new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
            },
        };
    }
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы