Введение в работу с JSON в C#
JSON (JavaScript Object Notation) — это легковесный формат обмена данными, который широко используется в веб-разработке, мобильных приложениях и микросервисах. Для C#-разработчика умение работать с JSON является обязательным навыком. В этой статье мы разберем основы парсинга (десериализации) и сериализации JSON с использованием современного пространства имен System.Text.Json, которое входит в состав .NET Core 3.0 и выше, а также .NET 5/6/7/8.
Мы рассмотрим:
- Что такое сериализация и десериализация
- Как преобразовать объект C# в JSON-строку
- Как прочитать JSON и превратить его обратно в объект
- Работу с вложенными объектами и коллекциями
- Обработку ошибок и настройку сериализации
Все примеры кода написаны для консольного приложения C# (.NET 6+). Вы сможете скопировать их и сразу запустить.
1. Основы сериализации: объект → JSON
Сериализация — это процесс преобразования объекта (или структуры данных) в строку формата JSON. В C# для этого используется класс JsonSerializer из пространства имен System.Text.Json.
Создаем простую модель
Допустим, у нас есть класс Person:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
}
Сериализация объекта
Теперь создадим экземпляр и преобразуем его в JSON:
using System.Text.Json;
Person person = new Person
{
Name = "Иван Петров",
Age = 30,
Email = "ivan@example.com"
};
string jsonString = JsonSerializer.Serialize(person);
Console.WriteLine(jsonString);
Результат:
{"Name":"Иван Петров","Age":30,"Email":"ivan@example.com"}
По умолчанию JsonSerializer использует camelCase для имен свойств (первая буква маленькая), но в нашем примере имена остались с заглавной буквы, так как мы не меняли настройки. Если вам нужен строгий camelCase, используйте JsonSerializerOptions:
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
string jsonCamelCase = JsonSerializer.Serialize(person, options);
Console.WriteLine(jsonCamelCase);
// {"name":"Иван Петров","age":30,"email":"ivan@example.com"}
2. Десериализация: JSON → объект
Десериализация — обратный процесс: мы берем JSON-строку и превращаем ее в объект C#.
Простой пример десериализации
Предположим, мы получили JSON от API:
string jsonFromApi = @"{""Name"":""Анна Смирнова"",""Age"":25,""Email"":""anna@test.com""}";
Person? personFromJson = JsonSerializer.Deserialize<Person>(jsonFromApi);
if (personFromJson != null)
{
Console.WriteLine($"Имя: {personFromJson.Name}, Возраст: {personFromJson.Age}");
}
Обратите внимание на знак ? после типа Person — это nullable-аннотация, указывающая, что результат может быть null (например, если JSON некорректен).
Работа с массивами и списками
Часто JSON содержит коллекции объектов. Допустим, у нас есть массив пользователей:
string jsonArray = @"
[
{""Name"":""Олег"",""Age"":35},
{""Name"":""Мария"",""Age"":28},
{""Name"":""Дмитрий"",""Age"":42}
]";
List<Person>? people = JsonSerializer.Deserialize<List<Person>>(jsonArray);
if (people != null)
{
foreach (var p in people)
{
Console.WriteLine($"{p.Name} - {p.Age} лет");
}
}
3. Работа с вложенными объектами и сложными структурами
Реальные JSON-данные редко бывают плоскими. Рассмотрим пример с вложенными объектами.
Модель с вложенностью
public class Company
{
public string Name { get; set; }
public Address Address { get; set; }
public List<Employee> Employees { get; set; }
}
public class Address
{
public string City { get; set; }
public string Street { get; set; }
}
public class Employee
{
public string FullName { get; set; }
public string Position { get; set; }
}
Сериализация сложной структуры
var company = new Company
{
Name = "TechCorp",
Address = new Address { City = "Москва", Street = "Тверская, 10" },
Employees = new List<Employee>
{
new Employee { FullName = "Сергей Иванов", Position = "Разработчик" },
new Employee { FullName = "Елена Козлова", Position = "Тестировщик" }
}
};
string companyJson = JsonSerializer.Serialize(company, new JsonSerializerOptions { WriteIndented = true });
Console.WriteLine(companyJson);
Результат (с форматированием):
{
"Name": "TechCorp",
"Address": {
"City": "Москва",
"Street": "Тверская, 10"
},
"Employees": [
{
"FullName": "Сергей Иванов",
"Position": "Разработчик"
},
{
"FullName": "Елена Козлова",
"Position": "Тестировщик"
}
]
}
Флаг WriteIndented = true делает JSON читаемым (с отступами). Для передачи по сети обычно используют компактный вариант (без отступов).
4. Настройка сериализации: атрибуты и обработка ошибок
Атрибуты для управления сериализацией
Вы можете управлять тем, как свойства преобразуются в JSON, с помощью атрибутов:
[JsonPropertyName("new_name")]— задает другое имя в JSON[JsonIgnore]— исключает свойство из JSON[JsonInclude]— включает приватное свойство
Пример:
<