Сериализация объектов в C# (.NET): JSON, XML и Binary

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Сериализация объектов в C# (.NET): JSON, XML и Binary

Сериализация — это процесс преобразования сложного объекта (или графа объектов) в поток байтов или текстовый формат (JSON, XML). Это необходимо для сохранения состояния объекта в файл, передачи данных по сети (REST API, gRPC) или кэширования. Обратный процесс — десериализация — восстанавливает объект из сериализованного представления. В экосистеме .NET (включая .NET Core и .NET 5/6/7/8) существует несколько встроенных механизмов сериализации.

1. System.Text.Json — современная сериализация в JSON

Начиная с .NET Core 3.0, Microsoft рекомендует использовать System.Text.Json как основной способ работы с JSON. Библиотека легковесна, высокопроизводительна и не требует сторонних зависимостей (в отличие от Newtonsoft.Json).

Пример базовой сериализации и десериализации

using System;
using System.Text.Json;

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public List<string> Hobbies { get; set; }
}

class Program
{
    static void Main()
    {
        var person = new Person
        {
            Name = "Алексей",
            Age = 30,
            Hobbies = new List<string> { "Чтение", "Программирование" }
        };

        // Сериализация
        string json = JsonSerializer.Serialize(person);
        Console.WriteLine(json);
        // {"Name":"Алексей","Age":30,"Hobbies":["Чтение","Программирование"]}

        // Десериализация
        Person restored = JsonSerializer.Deserialize<Person>(json);
        Console.WriteLine(restored.Name); // Алексей
    }
}

Настройка сериализации с помощью атрибутов

Вы можете управлять именами свойств в JSON, игнорировать null-значения или использовать кастомные конвертеры:

using System.Text.Json.Serialization;

public class Product
{
    [JsonPropertyName("product_id")]
    public int Id { get; set; }

    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    public string? Description { get; set; }

    [JsonConverter(typeof(JsonStringEnumConverter))]
    public Status Status { get; set; }
}

public enum Status { Active, Inactive }

2. XmlSerializer — сериализация в XML

Класс XmlSerializer (пространство имён System.Xml.Serialization) доступен во всех версиях .NET и идеально подходит для совместимости с унаследованными системами или конфигурационными XML-файлами.

Пример работы с XmlSerializer

using System;
using System.IO;
using System.Xml.Serialization;

[XmlRoot("Employee")]
public class Employee
{
    [XmlElement("FullName")]
    public string Name { get; set; }

    [XmlAttribute("id")]
    public int Id { get; set; }

    [XmlArray("Projects")]
    [XmlArrayItem("Project")]
    public List<string> Projects { get; set; }
}

class Program
{
    static void Main()
    {
        var emp = new Employee
        {
            Id = 101,
            Name = "Мария Иванова",
            Projects = new List<string> { "Alpha", "Beta" }
        };

        var serializer = new XmlSerializer(typeof(Employee));
        using (var writer = new StreamWriter("employee.xml"))
        {
            serializer.Serialize(writer, emp);
        }

        // Десериализация
        using (var reader = new StreamReader("employee.xml"))
        {
            Employee restored = (Employee)serializer.Deserialize(reader);
            Console.WriteLine(restored.Name); // Мария Иванова
        }
    }
}

Важно: XmlSerializer требует, чтобы класс имел публичный конструктор без параметров, а сериализуемые свойства были публичными и имели сеттеры.

3. BinaryFormatter (устарел, но упоминается для legacy)

Раньше System.Runtime.Serialization.Formatters.Binary.BinaryFormatter использовался для бинарной сериализации. Однако из-за проблем безопасности (уязвимости к десериализации атакующим) Microsoft объявила его устаревшим начиная с .NET 5. Не используйте его в новых проектах.

Вместо BinaryFormatter рассмотрите:

  • Protobuf-net — высокопроизводительная бинарная сериализация на основе Protocol Buffers (Google).
  • MessagePack — ещё один быстрый бинарный формат с поддержкой .NET.

4. Дополнительные возможности и рекомендации

  • Управление циклическими ссылками: System.Text.Json поддерживает ReferenceHandler.Preserve для сериализации графов с циклами.
  • Потоковая сериализация: Для больших данных используйте Utf8JsonWriter (JSON) или XmlWriter (XML) для записи без загрузки всего документа в память

Рекомендаций