Serialização e desserialização JSON (marshalling e unmarshalling) no .NET – visão geral

O namespace System.Text.Json apresenta funcionalidade para serialização e desserialização do JSON (JavaScript Object Notation). A Serialização é o processo de conversão do estado de um objeto, ou seja, os valores de suas propriedades, em um formulário que pode ser armazenado ou transmitido. O formulário serializado não inclui nenhuma informação sobre os métodos associados de um objeto. A desserialização reconstrói um objeto do formulário serializado.

O design da biblioteca System.Text.Json enfatiza o alto desempenho e a baixa alocação de memória em um amplo conjunto de recursos. O suporte interno a UTF-8 otimiza o processo de leitura e gravação de texto JSON codificado como UTF-8, que é a codificação mais predominante para dados na Web e arquivos em disco.

A biblioteca também fornece classes para trabalhar com um DOM (modelo de objeto do documento) na memória. Esse recurso permite o acesso aleatório aos elementos em uma cadeia de caracteres ou arquivo JSON.

Para o Visual Basic, há algumas limitações em quais partes da biblioteca você pode usar. Para saber mais, confira Suporte para Visual Basic.

Como obter a biblioteca

A biblioteca é interna como parte da estrutura compartilhada para o .NET Core 3.0 e versões posteriores. O recurso de geração de origem é interno e faz parte da estrutura compartilhada do .NET 6 e versões posteriores.

Para versões de estrutura anteriores ao .NET Core 3.0, instale o pacote do NuGet System.Text.Json. O pacote é compatível com:

  • .NET Standard 2.0 e posteriores
  • .NET Framework 4.6.2 e versões posteriores
  • .NET Core 2.1 e posteriores
  • .NET 5 e posteriores

Namespaces e APIs

  • O namespace System.Text.Json contém todos os pontos de entrada e os tipos principais.
  • O namespace System.Text.Json.Serialization contém atributos e APIs para cenários avançados e personalização específicos para serialização e desserialização.

Os exemplos de código mostrados neste artigo exigem diretivas using para um ou ambos os namespaces.

Importante

System.Text.Json não dá suporte às seguintes APIs de serialização que você pode ter usado anteriormente:

Métodos de extensão HttpClient e HttpContent

Serializar e desserializar cargas JSON da rede são operações comuns. Os métodos de extensão em HttpClient e HttpContent permitem que você faça essas operações em uma só linha de código. Esses métodos de extensão usam padrões da Web para JsonSerializerOptions.

O seguinte exemplo ilustra o uso de HttpClientJsonExtensions.GetFromJsonAsync e 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

Também há métodos de extensão para System.Text.Json em HttpContent.

Reflexão versus geração de origem

Por padrão, System.Text.Json reúne os metadados necessários para acessar propriedades de objetos para serialização e desserialização em tempo de execução usando reflexão. Como alternativa, System.Text.Json pode usar o recurso de geração de origem C# para melhorar o desempenho, reduzir o uso de memória privada e facilitar o corte do assembly, o que reduz o tamanho do aplicativo.

Para obter mais informações, confira Reflexão versus geração de origens.

Informações de segurança

Para informações sobre ameaças à segurança consideradas ao projetar JsonSerializer e como elas podem ser atenuadas, confira Modelo de riscoSystem.Text.Json.

Acesso thread-safe

O serializador System.Text.Json foi projetado com a segurança e o acesso thread-safe em mente. Na prática, isso significa que, uma vez bloqueadas, as instâncias de JsonSerializerOptions podem ser compartilhadas com segurança em vários threads. JsonDocument fornece uma representação do DOM imutável e no .NET 8 e versões posteriores, thread-safe, representação do DOM para valores JSON.

Recursos adicionais