Введение в работу с JSON на C#
JSON (JavaScript Object Notation) — это легковесный формат обмена данными, который широко используется в современных веб-приложениях, API и конфигурационных файлах. Для разработчика на C# умение работать с JSON — это обязательный навык, особенно при создании REST-клиентов, микросервисов или приложений, взаимодействующих с внешними источниками данных.
В экосистеме .NET существует два основных подхода к обработке JSON: классическая библиотека Newtonsoft.Json (также известная как Json.NET) и современная встроенная библиотека System.Text.Json, появившаяся в .NET Core 3.0 и ставшая стандартом в .NET 5+. Обе библиотеки позволяют выполнять две ключевые операции: сериализацию (преобразование объекта C# в строку JSON) и десериализацию (преобразование строки JSON обратно в объект C#).
В этой статье мы подробно разберём оба подхода, научимся парсить сложные структуры данных и рассмотрим лучшие практики работы с JSON в C#.
1. Базовые операции: сериализация и десериализация
1.1 Использование Newtonsoft.Json (Json.NET)
Newtonsoft.Json — это де-факто стандарт для работы с JSON в .NET на протяжении многих лет. Чтобы начать работу, установите пакет через NuGet:
Install-Package Newtonsoft.Json
Рассмотрим простой класс для примера:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public bool IsActive { get; set; }
}
Сериализация объекта в JSON:
using Newtonsoft.Json;
User user = new User
{
Id = 1,
Name = "Иван Петров",
Email = "ivan@example.com",
IsActive = true
};
string json = JsonConvert.SerializeObject(user, Formatting.Indented);
Console.WriteLine(json);
Результат выполнения:
{
"Id": 1,
"Name": "Иван Петров",
"Email": "ivan@example.com",
"IsActive": true
}
Десериализация JSON обратно в объект:
string jsonString = @"{""Id"":1,""Name"":""Иван Петров"",""Email"":""ivan@example.com"",""IsActive"":true}";
User deserializedUser = JsonConvert.DeserializeObject<User>(jsonString);
Console.WriteLine($"Пользователь: {deserializedUser.Name}, Email: {deserializedUser.Email}");
1.2 Использование System.Text.Json
Начиная с .NET Core 3.0, Microsoft представила собственную библиотеку System.Text.Json, которая оптимизирована по производительности и не требует внешних зависимостей.
Сериализация:
using System.Text.Json;
User user = new User
{
Id = 2,
Name = "Мария Смирнова",
Email = "maria@example.com",
IsActive = false
};
string json = JsonSerializer.Serialize(user, new JsonSerializerOptions
{
WriteIndented = true
});
Console.WriteLine(json);
Десериализация:
string jsonString = @"{""Id"":2,""Name"":""Мария Смирнова"",""Email"":""maria@example.com"",""IsActive"":false}";
User deserializedUser = JsonSerializer.Deserialize<User>(jsonString);
Console.WriteLine($"Пользователь: {deserializedUser.Name}");
2. Работа со сложными структурами данных
2.1 Вложенные объекты и коллекции
JSON часто содержит вложенные структуры. Рассмотрим пример с массивом заказов пользователя:
public class Order
{
public int OrderId { get; set; }
public decimal Amount { get; set; }
public List<string> Items { get; set; }
}
public class Customer
{
public int CustomerId { get; set; }
public string FullName { get; set; }
public List<Order> Orders { get; set; }
}
Десериализация сложного JSON (System.Text.Json):
string complexJson = @"
{
""CustomerId"": 101,
""FullName"": ""Алексей Иванов"",
""Orders"": [
{
""OrderId"": 5001,
""Amount"": 2500.50,
""Items"": [""Ноутбук"", ""Мышь""]
},
{
""OrderId"": 5002,
""Amount"": 800.00,
""Items"": [""Клавиатура""]
}
]
}";
Customer customer = JsonSerializer.Deserialize<Customer>(complexJson);
Console.WriteLine($"Клиент: {customer.FullName}, заказов: {customer.Orders.Count}");
foreach (var order in customer.Orders)
{
Console.WriteLine($" Заказ #{order.OrderId}: {order.Amount:C}, товары: {string.Join(", ", order.Items)}");
}
2.2 Обработка динамических данных
Иногда структура JSON заранее неизвестна. В таких случаях удобно использовать JObject (Newtonsoft.Json) или JsonDocument (System.Text.Json):
Newtonsoft.Json (JObject):
using Newtonsoft.Json.Linq;
string dynamicJson = @"{""name"":""Тест"",""values"":[1,2,3],""metadata"":{""version"":""1.0""}}";
JObject obj = JObject.Parse(dynamicJson);
string name = (string)obj["name"];
int firstValue = (int)obj["values"][0];
string version = (string)obj["metadata"]["version"];
Console.WriteLine($"Name: {name}, First value: {firstValue}, Version: {version}");
System.Text.Json (JsonDocument):
using System.Text.Json;
string dynamicJson = @"{""name"":""Тест"",""values"":[1,2,3],""metadata"":{""version"":""1.0""}}";
using JsonDocument doc = JsonDocument.Parse(dynamicJson);
JsonElement root = doc.RootElement;
string name = root.GetProperty("name").GetString();
int firstValue = root.GetProperty("values")[0].GetInt32();
string version = root.GetProperty("metadata").GetProperty("version").GetString();
Console.WriteLine($"Name: {name}, First value: {firstValue}, Version: {version}");
3. Настройка сериализации и атрибуты
3.1 Управление именами свойств
Часто имена свойств в JSON отличаются от стандартов C# (camelCase vs PascalCase). Для решения этой проблемы используются атрибуты:
Newtonsoft.Json:
using Newtonsoft