Сериализация и десериализация JSON (маршалинг и демаршалинг) в .NET — обзор

Пространство имен System.Text.Json предоставляет функциональные возможности для сериализации в нотацию объектов JavaScript (JSON) и десериализации объектов из этой нотации. Сериализация — это процесс преобразования состояния объекта, то есть значений его свойств в форму, которая может храниться или передаваться. Сериализованная форма не содержит никаких сведений о связанных методах объекта. Десериализация восстанавливает объект из сериализованной формы.

Дизайн System.Text.Json библиотеки подчеркивает высокую производительность и низкое выделение памяти по обширному набору функций. Встроенная поддержка UTF-8 оптимизирует процесс чтения и записи текста JSON в кодировке UTF-8, которая является наиболее распространенной кодировкой для данных в Интернете и файлов на диске.

Библиотека также предоставляет классы для работы с объектной моделью документа в памяти (DOM). Эта функция обеспечивает случайный доступ к элементам в JSON-файле или строке.

Для Visual Basic существуют некоторые ограничения на то, какие части библиотеки можно использовать. Дополнительные сведения см. в статье о поддержке Visual Basic.

Получение библиотеки

Библиотека входит в состав общей платформы для .NET Core 3.0 и более поздних версий. Функция создания источника встроена в общую платформу для .NET 6 и более поздних версий.

Для версий платформы, предшествующих .NET Core 3.0, установите System.Text.Json пакет NuGet. Пакет поддерживает:

  • .NET Standard 2.0 и более поздних версий
  • платформа .NET Framework 4.6.2 и более поздних версий
  • .NET Core 2.1 и более поздних версий
  • .NET 5 и более поздней версии

Пространства имен и API

  • Пространство имен System.Text.Json содержит все точки входа и основные типы.
  • Пространство имен System.Text.Json.Serialization содержит атрибуты и интерфейсы API для сложных сценариев и настройки, характерной для сериализации и десериализации.

В примерах кода, приведенных в этой статье, требуются using директивы для одного или обоих этих пространств имен.

Внимание

System.Text.Json не поддерживает следующие API сериализации, которые вы могли использовать ранее:

Методы расширения HttpClient и HttpContent

Сериализация и десериализация полезных данных JSON из сети являются обычными операциями. Методы расширения в HttpClient и HttpContent позволяют выполнять эти операции в одной строке кода. Эти методы расширения используют стандартные параметры веб-приложений для JsonSerializerOptions.

В следующем примере демонстрируется применение HttpClientJsonExtensions.GetFromJsonAsync и HttpClientJsonExtensions.PostAsJsonAsync:

using System.Net.Http.Json;

namespace HttpClientExtensionMethods
{
    public class User
    {
        public int Id { get; set; }
        public string? Name { get; set; }
        public string? Username { get; set; }
        public string? Email { get; set; }
    }

    public class Program
    {
        public static async Task Main()
        {
            using HttpClient client = new()
            {
                BaseAddress = new Uri("https://jsonplaceholder.typicode.com")
            };

            // Get the user information.
            User? user = await client.GetFromJsonAsync<User>("users/1");
            Console.WriteLine($"Id: {user?.Id}");
            Console.WriteLine($"Name: {user?.Name}");
            Console.WriteLine($"Username: {user?.Username}");
            Console.WriteLine($"Email: {user?.Email}");

            // Post a new user.
            HttpResponseMessage response = await client.PostAsJsonAsync("users", user);
            Console.WriteLine(
                $"{(response.IsSuccessStatusCode ? "Success" : "Error")} - {response.StatusCode}");
        }
    }
}

// Produces output like the following example but with different names:
//
//Id: 1
//Name: Tyler King
//Username: Tyler
//Email: Tyler @contoso.com
//Success - Created
Imports System.Net.Http
Imports System.Net.Http.Json

Namespace HttpClientExtensionMethods

    Public Class User
        Public Property Id As Integer
        Public Property Name As String
        Public Property Username As String
        Public Property Email As String
    End Class

    Public Class Program

        Public Shared Async Function Main() As Task
            Using client As New HttpClient With {
                .BaseAddress = New Uri("https://jsonplaceholder.typicode.com")
                }

                ' Get the user information.
                Dim user1 As User = Await client.GetFromJsonAsync(Of User)("users/1")
                Console.WriteLine($"Id: {user1.Id}")
                Console.WriteLine($"Name: {user1.Name}")
                Console.WriteLine($"Username: {user1.Username}")
                Console.WriteLine($"Email: {user1.Email}")

                ' Post a new user.
                Dim response As HttpResponseMessage = Await client.PostAsJsonAsync("users", user1)
                Console.WriteLine(
                $"{(If(response.IsSuccessStatusCode, "Success", "Error"))} - {response.StatusCode}")
            End Using
        End Function

    End Class

End Namespace

' Produces output like the following example but with different names:
'
'Id: 1
'Name: Tyler King
'Username: Tyler
'Email: Tyler @contoso.com
'Success - Created

Для System.Text.Json существуют также методы расширения на HttpContent.

Сравнение отражения и создания источника

По умолчанию собирает метаданные, System.Text.Json необходимые для доступа к свойствам объектов для сериализации и десериализации во время выполнения с помощью отражения. В качестве альтернативы можно использовать функцию создания источника C#, System.Text.Json чтобы повысить производительность, уменьшить использование частной памяти и упростить обрезку сборок, что сокращает размер приложения.

Дополнительные сведения см. в разделе Рефлексия и создание источника.

Сведения о безопасности

Сведения об угрозах безопасности, которые рассматривались при разработке JsonSerializerи способах их устранения, см. в статье System.Text.Json "Модель угроз".

Потокобезопасность

Сериализатор System.Text.Json был разработан с учетом безопасности потоков. Практически это означает, что после блокировки JsonSerializerOptions экземпляры можно безопасно совместно использовать в нескольких потоках. JsonDocument предоставляет неизменяемое представление и в .NET 8 и более поздних версиях, потокобезопасное, DOM-представление значений JSON.

Дополнительные ресурсы