JavaRush /Курси /C# SELF /Валідація JSON і <...

Валідація JSON і JSON Schema

C# SELF
Рівень 47 , Лекція 4
Відкрита

1. Вступ

Отже, ви вже вмієте перетворювати об’єкти на JSON (і назад). Але що робити, якщо на вхід вашого застосунку потрапляє щось… дивне? Наприклад, ви очікували ось такий JSON:

{
  "id": 123,
  "name": "Alice",
  "email": "alice@example.com"
}

А отримали ось що:

{
  "name": 42,
  "id": "not a number"
}

Так, серіалізатори C# чесно спробують десеріалізувати цей безлад, але часто це призводить до помилок під час виконання, втрати даних або навіть серйозних проблем для бізнесу. Перш ніж відправити дані далі, зберегти їх у базу чи надіслати мережею, перевірте, що дані валідні — інакше ваш код як акробат без страхівки.

Ось навіщо й потрібна валідація: це автоматична перевірка того, що JSON відповідає правилам — типам значень, обов’язковості полів, діапазонам, структурі тощо.

2. Які бувають способи валідації JSON?

У C# і .NET є три основні підходи:

  • Валідація власним кодом: вручну аналізуємо об’єкт, пишемо перевірки та генеруємо винятки у разі помилок.
  • Атрибути валідації на моделях: наприклад, [Required], [Range], [EmailAddress] з простору імен System.ComponentModel.DataAnnotations.
  • Валідація за допомогою JSON Schema — наш сьогоднішній герой!

JSON Schema — це стандарт, який дає змогу формально описати, як має виглядати валідний документ. Схема — це теж JSON. Ви визначаєте, які поля потрібні, яких вони типів, які значення допустимі тощо.

За допомогою схем ви описуєте:

  • Які поля мають бути.
  • Які типи очікуються (рядок, масив, число, об’єкт…).
  • Які поля обов’язкові, а які — ні.
  • Діапазони значень (наприклад, вік від 0 до 150).
  • Шаблони, довжини, переліки значень тощо.

Приклад найпростішої схеми

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "id":    { "type": "integer" },
    "name":  { "type": "string" }
  },
  "required": ["id", "name"]
}

3. Основні елементи JSON Schema

Розберімося на прикладах, що означають основні ключі в JSON Schema.

Ключ Опис Приклад
$schema
Посилання на версію стандарту JSON Schema
"https://json-schema.org/draft/2020-12/schema"
type
Тип значення (object, array, string, number тощо)
"type": "object"
properties
Опис властивостей об’єкта
"properties": { ... }
required
Масив обов’язкових полів
"required": ["id"]
items
Опис типу елементів масиву
"items": { ... }
enum
Перелік допустимих значень
"enum": ["A", "B"]
minimum
,
maximum
Обмеження для чисел
"minimum": 0
minLength
,
maxLength
Обмеження довжини рядків
"minLength": 3
pattern
Регулярний вираз для рядків
"pattern": "^[a-zA-Z]+$"

Наочно: приклад схеми для масиву людей

{
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "id":    { "type": "integer" },
      "name":  { "type": "string", "minLength": 2, "maxLength": 50 },
      "email": { "type": "string", "format": "email" }
    },
    "required": ["id", "name"]
  }
}

4. Як перевірити JSON на відповідність схемі у C#

У .NET стандартної підтримки JSON Schema немає (станом на .NET 9). На практиці використовують зовнішні бібліотеки: NJsonSchema або Newtonsoft.Json.Schema (Json.NET Schema).

Встановлення пакета Newtonsoft.Json.Schema (Json.NET Schema)

Виконайте в терміналі (у теці проєкту):

dotnet add package Newtonsoft.Json.Schema

Важливо: Newtonsoft.Json.Schema — комерційна бібліотека (для некомерційних цілей доступна безкоштовно). Підходить ідеально для pet-проєктів.

Приклад перевірки JSON на відповідність схемі

using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Schema;

string schemaJson = @"{
  'type': 'object',
  'properties': {
    'id':    { 'type': 'integer' },
    'name':  { 'type': 'string' },
    'email': { 'type': 'string', 'format': 'email' }
  },
  'required': ['id', 'name']
}";

// Уявімо, у нас є такий JSON
string json = @"{
  'id': 123,
  'name': 'Alice',
  'email': 'alice@example.com'
}";

// Спочатку парсимо схему
JSchema schema = JSchema.Parse(schemaJson);

// Парсимо сам JSON у JToken
JToken jsonObj = JToken.Parse(json);

// Перевіряємо, чи відповідає JSON схемі
bool valid = jsonObj.IsValid(schema, out IList<string> errors);

if (valid)
{
    Console.WriteLine("JSON валідний!");
}
else
{
    Console.WriteLine("JSON НЕ валідний!");
    foreach (var error in errors)
        Console.WriteLine(error);
}

Як використовувати перевірку JSON у застосунку?

Зазвичай так: спочатку — валідація (IsValid), далі — десеріалізація (JsonConvert.DeserializeObject<T>), і лише потім — бізнес-логіка. Так ви відсікаєте сміттєві дані на ранній стадії.

if (jsonObj.IsValid(schema))
{
    // Усе гаразд, можна десеріалізувати
    var person = JsonConvert.DeserializeObject<Person>(json);
}
else
{
    // Припинити обробку! Дані некоректні.
}

5. Застосування JSON Schema у реальному житті

Коли потрібна валідація?

  • Під час отримання даних через API (особливо від зовнішніх систем і різних клієнтів).
  • Під час міграції даних між мікросервісами та базами.
  • Під час генерації UI-форм та автозаповнення, якщо форму побудовано на основі схеми.
  • На співбесідах: питання «що, якщо прийшов неправильний JSON?» трапляється часто.

Цікавий момент для допитливих

  • Перевірка форматів: "format": "email", "date-time".
  • Складені правила: anyOf, oneOf, allOf.
  • Валідація вкладених об’єктів і масивів.
  • Розширення схем під власні потреби.

6. Великий практичний приклад

Вхідні дані (список користувачів):

[
  { "id": 1, "name": "Alice", "email": "alice@example.com" },
  { "id": 2, "name": "Bob" },
  { "id": "що це?", "name": 123, "email": "not-an-email" }
]

Схема:

{
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "id":    { "type": "integer" },
      "name":  { "type": "string", "minLength": 2, "maxLength": 50 },
      "email": { "type": "string", "format": "email" }
    },
    "required": ["id", "name"]
  }
}

Перевірка в .NET:

string jsonArray = @"[ ... ]"; // див. вище
string schemaJson = @"{ ... }"; // див. вище

JSchema schema = JSchema.Parse(schemaJson);
JToken arrayToken = JToken.Parse(jsonArray);

bool isValid = arrayToken.IsValid(schema, out IList<string> errs);
if (!isValid)
{
    foreach (var error in errs)
        Console.WriteLine(error);
    // Приклади повідомлень:
    // "String 'що це?' is not a valid integer."
    // "Integer 123 is not a valid string."
    // "String 'not-an-email' is not a valid email address."
}

7. Типові помилки під час роботи з JSON-схемами

Помилка №1: невідповідність схеми й актуальних даних. Після зміни моделі забувають оновити схему. Валідація або пропускає помилки, або блокує коректні дані.

Помилка №2: невідповідність типів у схемі та в моделі. Поле в моделі змінило тип (наприклад, id став рядком), а в схемі лишився integer — валідатор почне повідомляти про помилки.

Помилка №3: відсутність обов’язкових для бізнесу полів. Навіть якщо поле не позначене як обов’язкове, логіка може на нього спиратися — його відсутність призведе до збоїв.

Помилка №4: некоректний формат даних. Поле типу string з email або датою виглядає «як рядок», але може бути невалідним. Використовуйте format та/або додаткові перевірки.

Помилка №5: реалізація бібліотеки відстає від стандарту. Стандарт розвивається, а бібліотеки — не завжди встигають. Деякі перевірки можуть бути відсутні або працювати інакше.

1
Опитування
Робота з JSON-даними, рівень 47, лекція 4
Недоступний
Робота з JSON-даними
Основи синтаксису та структури JSON
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ