Содержание
Что касается веб-технологий, то здесь, в отличие от того же C# с давних времен присутствует некий «плюрализм мнений» относительно того, что правильно, а что нет. Так, например, некоторое время назад (да, похоже, и сейчас) не считается чем-то проблемным «забыть» какой-нибудь закрывающий html-тег в разметке страницы — браузер сам «разрулит» проблему. Не стал исключением в этом плане и формат JSON. Например, вы можете встретить такие «стандартные» невалидные JSON-объекты у которых числа записаны в кавычках, или объект заканчивается запятой («},») или же в объекте содержатся комментарии, которые, по-хорошему, вообще не должны присутствовать в JSON. Разработчики System.Text.Json предусмотрели подобные моменты при разработке классов для работы с JSON в C# и усовершенствовали их работу в .NET 5.
Пример невалидного JSON-объекта для работы
Допустим, мы разрабатываем приложение для работы с API какого-нибудь сервера в Сети. Естественно, что мы никак не можем повлиять на то, в какой форме этот сервер нам отвечает, а отвечает он нам на очередной запрос вот таким JSON-объектом:
{ "Login": "Uasya", //логин "Password": "qwerty", //это пароль "Name": "Вася", "PersonFamily": "Пупкин", "Age": "38", //возраст "Birthday": "1983-01-16T00:00:00" }
Здесь сразу три проблемы, которые не позволят нам десериализовать этот JSON в объект C#:
- Комментарии в JSON
- Числовое значение (возраст) записано как строка
Попытка десериализовать такой JSON в объект:
public class Person { public string Name { get; set; } [JsonPropertyName("PersonFamily")] public string Surname { get; set; } public int age; public int Age //теперь свойство Age не будет сериализоваться { get => age; set { if ((value < 0) || (value > 100)) throw new Exception("Возраст должен находится в интервале от 0 до 100 лет"); else age = value; } } public DateTime Birthday { get; set; } public Person(string name) { Name = name; } public Person() { } }
приведет к исключению:
Разрешить использовать такой JSON в своем приложении нам помогут настройки сериализации.
Разрешаем использовать невалидный JSON в C#
Настроим десериализацию объекта следующим образом:
JsonSerializerOptions options = new JsonSerializerOptions() { WriteIndented = true, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,//не экранирем символы ReadCommentHandling = JsonCommentHandling.Skip, //комментарии в JSON пропускаем NumberHandling = JsonNumberHandling.AllowReadingFromString //разрешаем читать числа из строк };
Теперь попробуем десериализовать объект. Получим следующий результат:
Фамилия: Пупкин
Возвраст: 38
День рождения: 16.01.1983 0:00:00
NumberHandling
появилась только в .NET 5. В .NET Core 3.1 такой настройки нетИтого
Сериализатор JsonSerializer
позволяет десериализировать JSON-объекты, которые формально можно считать невалидными (содержащими ошибки). Для десериализации таких объектов можно воспользоваться настройками сериализатора ReadCommentHandling
и NumberHandling
.