Содержание
Что касается веб-технологий, то здесь, в отличие от того же 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.