Как настроить сериализацию с System.Text.Json в C#: кратко для новичков

1d26ab82cf26eb7c72febb728f6f42be.png

Привет, Хабр!

Сегодня поговорим о том, как сериализовать данные в C# с помощью библиотеки System.Text.Json. Если вы раньше использовали Newtonsoft.Json для преобразования объектов в JSON и обратно, то пришло время посмотреть, как этот процесс можно ускорить и упростить, применяя встроенные инструменты .NET.

System.Text.Json

Сначала взглянем на самый простой сценарий — сериализация объектов в JSON и обратное преобразование. System.Text.Json имеет много методов для работы с JSON, и основные из них — это JsonSerializer.Serialize() и JsonSerializer.Deserialize():

using System.Text.Json;

public class Employee
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int EmployeeId { get; set; }
}

var employee = new Employee 
{
    FirstName = "Vasya",
    LastName = "Pupkin",
    EmployeeId = 1234
};

// сериализация объекта Employee в строку JSON
string json = JsonSerializer.Serialize(employee);
Console.WriteLine(json);  // {"FirstName":"Vasya","LastName":"Pupkin","EmployeeId":1234}

// десериализация JSON обратно в объект Employee
Employee deserializedEmployee = JsonSerializer.Deserialize(json);
Console.WriteLine(deserializedEmployee.FirstName);  // Vasya

Всё просто: создаешь объект, сериализуешь его в строку JSON и обратно.

Вложенные объекты

public class Address
{
    public string City { get; set; }
    public string Country { get; set; }
}

public class Employee
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int EmployeeId { get; set; }
    public Address EmployeeAddress { get; set; }
}

var employee = new Employee
{
    FirstName = "Nastya",
    LastName = "Orlova",
    EmployeeId = 1234,
    EmployeeAddress = new Address { City = "New York", Country = "USA" }
};

string json = JsonSerializer.Serialize(employee);
Console.WriteLine(json);  
// {"FirstName":"Nastya","LastName":"Orlova","EmployeeId":1234,"EmployeeAddress":{"City":"New York","Country":"USA"}}

Employee deserializedEmployee = JsonSerializer.Deserialize(json);
Console.WriteLine(deserializedEmployee.EmployeeAddress.City);  // New York

JSON работает с вложенными объектами так же, как и с простыми, сериализация происходит рекурсивно.

System.Text.Json позволяет настроить процесс сериализации через JsonSerializerOptions. Например, можно управлять форматированием JSON или игнорировать значения null.

Пример:

var options = new JsonSerializerOptions
{
    WriteIndented = true,  // Включаем красивое форматирование
    DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull  // Игнорируем null значения
};

var employee = new Employee
{
    FirstName = "Sonya",
    LastName = null,  // Это поле будет проигнорировано
    EmployeeId = 1234
};

string json = JsonSerializer.Serialize(employee, options);
Console.WriteLine(json);
// {
//   "FirstName": "Sonya",
//   "EmployeeId": 1234
// }

Опция WriteIndented хороша, когда нужно сделать JSON более читаемым, например, для логирования. А вот DefaultIgnoreCondition позволяет игнорировать пустые или null поля — удобно для экономии места в передаваемых данных.

Еще можно обрабатывать данные, которые не поддерживаются по умолчанию. Например, сложные объекты или специфические форматы. Для этого нужно создать кастомный конвертер с помощью JsonConverter.

Пример кастомного конвертера для DateTime:

public class CustomDateTimeConverter : JsonConverter
{
    private const string Format = "yyyy-MM-dd";

    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        string dateString = reader.GetString();
        return DateTime.ParseExact(dateString, Format, null);
    }

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString(Format));
    }
}

var options = new JsonSerializerOptions
{
    Converters = { new CustomDateTimeConverter() },
    WriteIndented = true
};

DateTime now = DateTime.Now;
string json = JsonSerializer.Serialize(now, options);
Console.WriteLine(json);  // "2024-09-07"

Здесь переопределяем методы Read и Write, чтобы работать с датами в специфичном формате.

Асинхронная сериализация

Когда работаем с потоками или большими объемами данных, асинхронные операции помогают избежать блокировок:

using (FileStream fs = new FileStream("data.json", FileMode.Create))
{
    var employee = new Employee { FirstName = "Alex", LastName = "Champion", EmployeeId = 1234 };
    await JsonSerializer.SerializeAsync(fs, employee);
}

Сериализация в байты

Если нужно максимизировать производительность, можно сериализовать объект в массив байт, что ускоряет передачу данных:

byte[] jsonBytes = JsonSerializer.SerializeToUtf8Bytes(employee);

Это на 5–10% быстрее, чем обычная сериализация в строку.

JsonDocument

Если нужно читать или манипулировать большими JSON-структурами, которые сложно или нежелательно сериализовать в объект, то в помощь идет JsonDocument:

string jsonString = "{\"FirstName\":\"Artem\",\"LastName\":\"Artemovich\",\"EmployeeId\":1234}";
using (JsonDocument doc = JsonDocument.Parse(jsonString))
{
    JsonElement root = doc.RootElement;
    string firstName = root.GetProperty("FirstName").GetString();
    Console.WriteLine(firstName); 
}

Этот подход позволяет работать с JSON на уровне элементов, не создавая для этого целые объекты.

Итог: System.Text.Json — это мощный инструмент для работы с JSON в C#. Он позволяет легко сериализовать и десериализовать объекты, и к тому же настраивать процесс, используя различные опции и кастомные конвертеры.

Как эффективно использовать асинхронность в C# для улучшения производительности приложений? Обсудим это на открытом уроке 12 сентября. Какие темы успеем затронуть:

  • Основы асинхронности в C#: рассмотрим ключевые концепции и принципы асинхронного программирования.

  • Async и Await: подробно разберем ключевые слова async и await, их использование и влияние на код.

  • Лучшие практики: Советы и рекомендации по оптимизации и улучшению асинхронного кода.

Записаться на урок можно на странице курса «C# Developer. Professional».

© Habrahabr.ru