JSON в C# классы: генерация POCO
Автоматическая генерация C# классов из JSON, атрибуты сериализации, использование с Newtonsoft.Json.
Посчитайте прямо здесь: JSON → C# Class
Открыть инструмент целиком →Введение
Работа с JSON в C# требует классов, в которые десериализуется ответ API. Написание этих классов вручную — утомительное занятие, особенно для больших контрактов с десятками полей и вложенных объектов. К счастью, процесс можно автоматизировать: существуют инструменты, которые генерируют C# классы из JSON за секунды. В этой статье разберём подходы, атрибуты сериализации и лучшие практики работы с JSON в .NET.
Что такое POCO
POCO (Plain Old CLR Object) — простой класс без инфраструктурных зависимостей, только свойства и конструкторы. В контексте JSON-сериализации POCO — это класс, описывающий структуру данных. Например:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public List<string> Roles { get; set; }
public bool Active { get; set; }
}Сериализатор (Newtonsoft.Json или System.Text.Json) преобразует JSON в экземпляр этого класса и обратно. Имена свойств в C# обычно пишутся в PascalCase, а JSON-ключи часто в camelCase или snake_case — этот зазор решается атрибутами или настройками сериализатора.
Пример: из JSON в C# класс
Исходный JSON:
{
"userId": 42,
"userName": "Анна Иванова",
"isActive": true,
"address": {
"city": "Москва",
"zipCode": "101000"
},
"tags": ["admin", "editor"]
}Сгенерированные классы:
public class Address
{
[JsonPropertyName("city")]
public string City { get; set; }
[JsonPropertyName("zipCode")]
public string ZipCode { get; set; }
}
public class UserResponse
{
[JsonPropertyName("userId")]
public int UserId { get; set; }
[JsonPropertyName("userName")]
public string UserName { get; set; }
[JsonPropertyName("isActive")]
public bool IsActive { get; set; }
[JsonPropertyName("address")]
public Address Address { get; set; }
[JsonPropertyName("tags")]
public List<string> Tags { get; set; }
}Атрибуты сериализации
System.Text.Json
Современный сериализатор от Microsoft, встроен в .NET Core 3.0+ и .NET 5+. Атрибут[JsonPropertyName("name")] указывает имя JSON-поля. Опционально можно использовать [JsonIgnore] для пропуска свойства и[JsonConverter(typeof(...))] для кастомной конвертации.
Newtonsoft.Json
Самая популярная сторонняя библиотека для работы с JSON в C#. Атрибут[JsonProperty("name")] делает то же самое. Дополнительные возможности:[JsonIgnore], [JsonConverter(typeof(...))],[JsonObject] для настройки класса. Newtonsoft гибче System.Text.Json, но медленнее.
| Атрибут | System.Text.Json | Newtonsoft.Json |
|---|---|---|
| Имя поля | [JsonPropertyName] | [JsonProperty] |
| Игнорировать | [JsonIgnore] | [JsonIgnore] |
| Конвертер | [JsonConverter] | [JsonConverter] |
| Обязательное поле | [JsonRequired] | [JsonProperty(Required = ...)] |
| Имя перечисления | [JsonStringEnumConverter] | [StringEnumConverter] |
Выбор между System.Text.Json и Newtonsoft
Microsoft рекомендует System.Text.Json для новых проектов: он встроен в платформу, быстрее и активно развивается. Newtonsoft остаётся стандартом в legacy-коде и там, где нужна максимальная гибкость (например, сложные кастомные конвертеры, динамическая десериализация). Для большинства современных API System.Text.Json достаточно.
Инструменты генерации
Онлайн-генератор
Самый быстрый способ — наш инструмент JSON в C#. Вставляете JSON, выбираете сериализатор (System.Text.Json или Newtonsoft), получаете готовые классы. Все вычисления происходят локально в браузере.
Visual Studio: Paste Special
В Visual Studio есть встроенная функция: Edit → Paste Special → Paste JSON as Classes. Скопируйте JSON в буфер, откройте C#-файл, выполните команду — студия сгенерирует классы. Удобно, но требует Visual Studio (не работает в VS Code).
quicktype
Мощный CLI и веб-инструмент, поддерживает C#, TypeScript, Go, Rust, Java, Swift и другие языки. Умеет читать JSON-файлы, URL и генерировать код с настройками.
# Установка
dotnet tool install --global quicktype
# Генерация
quicktype user.json -o User.cs --lang csharp
quicktype https://api.example.com/users -o User.cs --lang csharpSource generators
В .NET 6+ появились source generators для System.Text.Json: они генерируют сериализацию на этапе компиляции, что ускоряет работу и уменьшает размер рефлексии. Для использования пометьте класс атрибутом [JsonSerializable(typeof(User))]в отдельном JsonSerializerContext.
Сложные случаи
Словари с произвольными ключами
Если в JSON есть объект с произвольными ключами (например, идентификаторы как ключи), используйте Dictionary<string, T>:
public class UsersResponse
{
public Dictionary<int, User> Users { get; set; }
}Необязательные поля
Поля, которые могут отсутствовать в JSON, делайте nullable (string?, int?) или используйте значение по умолчанию:
public class User
{
public int Id { get; set; }
public string? MiddleName { get; set; } // может быть null
public int Age { get; set; } = 0; // дефолт
}Перечисления (enum)
По умолчанию enum сериализуется как число. Чтобы передавать строковое значение, используйте конвертер:
public enum UserRole
{
Admin,
Editor,
Reader
}
public class User
{
[JsonConverter(typeof(JsonStringEnumConverter))]
public UserRole Role { get; set; }
}Полиморфизм
Если в JSON могут быть объекты разных типов (например, разные виды платежей), используйте атрибуты [JsonDerivedType] в System.Text.Json или[JsonConverter] с кастомной логикой в Newtonsoft.
Лучшие практики
- Используйте PascalCase для свойств — это соглашение в C#. Маппинг на camelCase или snake_case делайте через атрибуты.
- Делайте свойства nullable там, где поле опционально — это упрощает работу и явно выражает контракт.
- Не используйте публичные поля — свойства с
{ get; set; }предпочтительнее, сериализаторы с ними работают лучше. - Добавляйте атрибуты к каждому свойству — даже если имя совпадает, это сделает контракт явным и устойчивым к переименованиям.
- Регенерируйте классы при изменении API — добавьте шаг в CI для проверки, что типы актуальны.
- Используйте record для иммутабельных DTO — современные C# records отлично подходят для API-моделей.
- Валидируйте данные — JSON-классы описывают структуру, но не бизнес-правила. Для валидации используйте DataAnnotations или FluentValidation.
Пример с record
public record User(
[property: JsonPropertyName("id")] int Id,
[property: JsonPropertyName("name")] string Name,
[property: JsonPropertyName("email")] string Email
);Десериализация
После генерации классов десериализация сводится к одной строке:
// System.Text.Json
using System.Text.Json;
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
};
var user = JsonSerializer.Deserialize<User>(jsonString, options);
// Newtonsoft.Json
using Newtonsoft.Json;
var user = JsonConvert.DeserializeObject<User>(jsonString);Для HTTP-запросов в .NET используйте HttpClient.GetFromJsonAsync<T>()— это расширение само десериализует ответ.
Связанные инструменты
Если вы работаете в полиглот-команде, кроме генерации C# классов пригодятсяJSON в TypeScript для фронтенда и другие конвертеры ConvertHub. Для форматирования и валидации JSON используйтеJSON форматтер, а для извлечения конкретных полей — JSONPath.
Заключение
Генерация C# классов из JSON — рутинная операция, которую лучше автоматизировать. Для разовых задач используйте онлайн-генератор ConvertHub или встроенную функцию Visual Studio, для регулярных — quicktype. При выборе сериализатора ориентируйтесь на System.Text.Json для новых проектов и Newtonsoft для legacy. И не забывайте про best practices: PascalCase, nullable для опциональных полей, явные атрибуты и регулярную регенерацию при изменении API. Это сэкономит часы ручной работы и снизит количество багов в интеграции.
Попробуйте эти инструменты
Похожие статьи
JSON vs XML — какое выбрать для проекта
Сравнение JSON и XML: синтаксис, размер, скорость парсинга, читаемость. Когда JSON лучше, а когда XML.
JSON форматтер: зачем нужен и как использовать
Что такое форматирование JSON, отступы и пробелы, валидация, minify vs beautify, лучшие практики.
CSV в JSON: конвертация и когда нужна
Как преобразовать CSV в JSON, структура данных, обработка больших файлов, использование в JavaScript.
YAML — конфигурационный формат: полный гид
Синтаксис YAML, отступы, типы данных, отличие от JSON, использование в Docker, Kubernetes, CI/CD.