Avatar ·

Как преобразовать объект C# в JSON-строку в .NET?

Всем привет! Я новичок в C# и .NET, и у меня возникла проблема. Мне нужно отправить данные с моего десктопного приложения на сервер в виде JSON. Я создал простой класс для хранения информации о пользователе: ```csharp public class User { public string Name { get; set; } public int Age { get; set; } public string Email { get; set; } } ``` Затем я создаю объект этого класса и заполняю его данными: ```csharp User user = new User { Name = "Иван Петров", Age = 30, Email = "ivan@example.com" }; ``` Теперь мне нужно превратить этот объект в строку JSON, чтобы отправить её через HTTP-запрос. Я слышал, что в .NET есть встроенные средства для этого, но не могу разобраться, как их правильно использовать. Пробовал гуглить, но нахожу много устаревших примеров с JavaScriptSerializer или DataContractJsonSerializer, и не понимаю, какой из них сейчас актуален. Подскажите, пожалуйста, как правильно и современно сериализовать объект C# в JSON в .NET (я использую .NET 6)? И нужно ли для этого устанавливать какие-то дополнительные пакеты через NuGet? Заранее спасибо! (Пожалуйста, напишите ответ с примером кода, который я могу сразу скопировать и использовать.) <<>>

Использование System.Text.Json (рекомендуемый способ)

Начиная с .NET Core 3.0 и во всех более новых версиях (.NET 5, 6, 7, 8 и далее), Microsoft рекомендует использовать пространство имён System.Text.Json. Это современная, высокопроизводительная и встроенная библиотека для работы с JSON, которая не требует установки дополнительных пакетов (она уже включена в базовую поставку .NET).

Простой пример сериализации

Вот как преобразовать ваш объект User в JSON-строку:

using System.Text.Json;

// Ваш класс
public class User
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Email { get; set; }
}

// Создаём объект
var user = new User
{
    Name = "Иван Петров",
    Age = 30,
    Email = "ivan@example.com"
};

// Сериализуем в JSON
string jsonString = JsonSerializer.Serialize(user);

Console.WriteLine(jsonString);
// Вывод: {"Name":"Иван Петров","Age":30,"Email":"ivan@example.com"}

Настройка сериализации

Часто требуется изменить стандартное поведение. Например, использовать camelCase для имён свойств (как принято в JavaScript) или игнорировать null-значения. Это делается через JsonSerializerOptions:

var options = new JsonSerializerOptions
{
    // Имена свойств в camelCase (name, age, email)
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    // Не включать в JSON свойства со значением null
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
    // Форматирование с отступами (читаемый JSON)
    WriteIndented = true
};

string jsonFormatted = JsonSerializer.Serialize(user, options);
Console.WriteLine(jsonFormatted);
/* Вывод:
{
  "name": "Иван Петров",
  "age": 30,
  "email": "ivan@example.com"
}
*/

Обратная операция — десериализация

Чтобы превратить JSON обратно в объект C#, используйте JsonSerializer.Deserialize<T>():

string jsonInput = @"{""Name"":""Мария"",""Age"":25,""Email"":""maria@test.com""}";
User deserializedUser = JsonSerializer.Deserialize<User>(jsonInput);
Console.WriteLine(deserializedUser.Name); // Мария

Важные моменты

  • Публичные свойства: По умолчанию сериализуются только публичные свойства с геттерами и сеттерами. Поля (public string name;) не сериализуются.
  • Атрибуты: Вы можете управлять сериализацией с помощью атрибутов, например [JsonPropertyName("custom_name")] для переименования поля или [JsonIgnore] для исключения свойства.
  • Циклические ссылки: Если у вас есть ссылки друг на друга (например, объект A содержит объект B, а B содержит A), по умолчанию возникнет исключение. Используйте ReferenceHandler.IgnoreCycles в опциях.
  • Производительность: System.Text.Json работает очень быстро и не уступает Newtonsoft.Json, а в некоторых сценариях даже быстрее.

Что насчёт Newtonsoft.Json (Json.NET)?

До появления System.Text.Json стандартом де-факто была библиотека Newtonsoft.Json (устанавливается через NuGet). Она до сих пор популярна и имеет больше возможностей (например, поддержка динамических типов, более гибкие конвертеры). Если вы работаете с унаследованным кодом или вам нужны специфические функции, можете использовать её:

// Установите пакет: Install-Package Newtonsoft.Json
using Newtonsoft.Json;

string json = JsonConvert.SerializeObject(user);
// или с настройками:
string jsonIndented = JsonConvert.SerializeObject(user, Formatting.Indented);

Но для новых проектов на .NET 6+ я настоятельно рекомендую System.Text.Json — он не требует внешних зависимостей и полностью поддерживается Microsoft.

<<>>

Альтернативный подход: использование атрибутов для точного контроля

Если вам нужно тонко настроить, какие поля попадут в JSON и как они будут называться, используйте атрибуты из пространства имён System.Text.Json.Serialization. Это особенно полезно, когда ваш класс отличается от структуры JSON, которую ожидает API.

Пример с атрибутами:

using System.Text.Json.Serialization;

public class User
{
    // Переименуем свойство в "full_name"
    [JsonPropertyName("full_name")]
    public string Name { get; set; }

    // Исключим из JSON, если возраст не указан
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
    public int Age { get; set; }

    // Всегда включаем email
    public string Email { get; set; }

    // Это свойство не будет сериализовано
    [JsonIgnore]
    public string Password { get; set; }
}

// Использование
var user = new User { Name = "Анна", Age = 0, Email = "anna@test.com", Password = "secret" };
string json = JsonSerializer.Serialize(user);
// Результат: {"full_name":"Анна","Email":"anna@test.com"}
// Age не попал в JSON, так как равен 0 (значение по умолчанию), а Password скрыт

Когда это полезно?

  • Когда JSON-ключи должны отличаться от имён свойств в C# (например, snake_case или сокращения).
  • Когда нужно скрыть чувствительные данные (пароли, токены) от сериализации.
  • Когда нужно условно включать/исключать поля в зависимости от их значения.

Этот подход даёт максимальный контроль без написания кастомных конвертеров и отлично комбинируется с JsonSerializerOptions.