Como escrever objetos .NET como JSON (serializar)

Este artigo mostra como usar o namespace System.Text.Json para serializar em JSON (JavaScript Object Notation). Se você estiver portando o código existente de Newtonsoft.Json, confira Como migrar para System.Text.Json.

Dica

Você pode usar a assistência de IA para serializar para JSON com o GitHub Copilot.

Para gravar JSON em uma cadeia de caracteres ou em um arquivo, chame o método JsonSerializer.Serialize.

Exemplos de serialização

O seguinte exemplo cria JSON como uma cadeia de caracteres:

using System.Text.Json;

namespace SerializeBasic
{
    public class WeatherForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
    }

    public class Program
    {
        public static void Main()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot"
            };

            string jsonString = JsonSerializer.Serialize(weatherForecast);

            Console.WriteLine(jsonString);
        }
    }
}
// output:
//{"Date":"2019-08-01T00:00:00-07:00","TemperatureCelsius":25,"Summary":"Hot"}
Dim jsonString As String

A saída JSON é minimizada (os caracteres de espaço em branco, recuo e de nova linha são removidos) por padrão.

O seguinte exemplo usa código síncrono para criar um arquivo JSON:

using System.Text.Json;

namespace SerializeToFile
{
    public class WeatherForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
    }

    public class Program
    {
        public static void Main()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot"
            };

            string fileName = "WeatherForecast.json"; 
            string jsonString = JsonSerializer.Serialize(weatherForecast);
            File.WriteAllText(fileName, jsonString);

            Console.WriteLine(File.ReadAllText(fileName));
        }
    }
}
// output:
//{"Date":"2019-08-01T00:00:00-07:00","TemperatureCelsius":25,"Summary":"Hot"}
jsonString = JsonSerializer.Serialize(weatherForecast1)
File.WriteAllText(fileName, jsonString)

O seguinte exemplo usa código assíncrono para criar um arquivo JSON:

using System.Text.Json;

namespace SerializeToFileAsync
{
    public class WeatherForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
    }

    public class Program
    {
        public static async Task Main()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot"
            };

            string fileName = "WeatherForecast.json";
            await using FileStream createStream = File.Create(fileName);
            await JsonSerializer.SerializeAsync(createStream, weatherForecast);

            Console.WriteLine(File.ReadAllText(fileName));
        }
    }
}
// output:
//{"Date":"2019-08-01T00:00:00-07:00","TemperatureCelsius":25,"Summary":"Hot"}
Dim createStream As FileStream = File.Create(fileName)
Await JsonSerializer.SerializeAsync(createStream, weatherForecast1)

Os exemplos anteriores usam inferência de tipos para o tipo que está sendo serializado. Uma sobrecarga de Serialize() usa um parâmetro de tipo genérico:

using System.Text.Json;

namespace SerializeWithGenericParameter
{
    public class WeatherForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
    }

    public class Program
    {
        public static void Main()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot"
            };

            string jsonString = JsonSerializer.Serialize<WeatherForecast>(weatherForecast);

            Console.WriteLine(jsonString);
        }
    }
}
// output:
//{"Date":"2019-08-01T00:00:00-07:00","TemperatureCelsius":25,"Summary":"Hot"}
jsonString = JsonSerializer.Serialize(Of WeatherForecastWithPOCOs)(weatherForecast)

Também é possível usar o GitHub Copilot para gerar código de serialização para você. Para obter instruções, consulte a seção Usar o GitHub Copilot neste artigo.

Comportamento de serialização

Quando você usa System.Text.Json indiretamente em um aplicativo ASP.NET Core, alguns comportamentos padrão são diferentes. Para obter mais informações, confira Padrões da Web para JsonSerializerOptions.

Os tipos compatíveis incluem:

Você pode implementar conversores personalizados para lidar com tipos adicionais ou fornecer funcionalidades que não são compatíveis com os conversores internos.

Veja um exemplo mostrando como uma classe que contém propriedades de coleção e um tipo definido pelo usuário é serializada:

using System.Text.Json;

namespace SerializeExtra
{
    public class WeatherForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
        public string? SummaryField;
        public IList<DateTimeOffset>? DatesAvailable { get; set; }
        public Dictionary<string, HighLowTemps>? TemperatureRanges { get; set; }
        public string[]? SummaryWords { get; set; }
    }

    public class HighLowTemps
    {
        public int High { get; set; }
        public int Low { get; set; }
    }

    public class Program
    {
        public static void Main()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot",
                SummaryField = "Hot",
                DatesAvailable = new List<DateTimeOffset>() 
                    { DateTime.Parse("2019-08-01"), DateTime.Parse("2019-08-02") },
                TemperatureRanges = new Dictionary<string, HighLowTemps>
                    {
                        ["Cold"] = new HighLowTemps { High = 20, Low = -10 },
                        ["Hot"] = new HighLowTemps { High = 60 , Low = 20 }
                    },
                SummaryWords = new[] { "Cool", "Windy", "Humid" }
            };

            var options = new JsonSerializerOptions { WriteIndented = true };
            string jsonString = JsonSerializer.Serialize(weatherForecast, options);

            Console.WriteLine(jsonString);
        }
    }
}
// output:
//{
//  "Date": "2019-08-01T00:00:00-07:00",
//  "TemperatureCelsius": 25,
//  "Summary": "Hot",
//  "DatesAvailable": [
//    "2019-08-01T00:00:00-07:00",
//    "2019-08-02T00:00:00-07:00"
//  ],
//  "TemperatureRanges": {
//    "Cold": {
//      "High": 20,
//      "Low": -10
//    },
//    "Hot": {
//    "High": 60,
//      "Low": 20
//    }
//  },
//  "SummaryWords": [
//    "Cool",
//    "Windy",
//    "Humid"
//  ]
//}
Public Class WeatherForecastWithPOCOs
    Public Property [Date] As DateTimeOffset
    Public Property TemperatureCelsius As Integer
    Public Property Summary As String
    Public SummaryField As String
    Public Property DatesAvailable As IList(Of DateTimeOffset)
    Public Property TemperatureRanges As Dictionary(Of String, HighLowTemps)
    Public Property SummaryWords As String()
End Class

Public Class HighLowTemps
    Public Property High As Integer
    Public Property Low As Integer
End Class

' serialization output formatted (pretty-printed with whitespace and indentation):
' {
'   "Date": "2019-08-01T00:00:00-07:00",
'   "TemperatureCelsius": 25,
'   "Summary": "Hot",
'   "DatesAvailable": [
'     "2019-08-01T00:00:00-07:00",
'     "2019-08-02T00:00:00-07:00"
'   ],
'   "TemperatureRanges": {
'     "Cold": {
'       "High": 20,
'       "Low": -10
'     },
'     "Hot": {
'       "High": 60,
'       "Low": 20
'     }
'   },
'   "SummaryWords": [
'     "Cool",
'     "Windy",
'     "Humid"
'   ]
' }

Serializar para UTF-8

É 5 a 10% mais rápido serializar para uma matriz de bytes UTF-8 do que usar os métodos baseados em cadeia de caracteres. Isso ocorre porque os bytes (como UTF-8) não precisam ser convertidos em cadeias de caracteres (UTF-16).

Para serializar para uma matriz de bytes UTF-8, chame o método JsonSerializer.SerializeToUtf8Bytes:

byte[] jsonUtf8Bytes =JsonSerializer.SerializeToUtf8Bytes(weatherForecast);
Dim jsonUtf8Bytes As Byte()
Dim options As JsonSerializerOptions = New JsonSerializerOptions With {
    .WriteIndented = True
}
jsonUtf8Bytes = JsonSerializer.SerializeToUtf8Bytes(weatherForecast1, options)

Uma sobrecarga Serialize que usa um Utf8JsonWriter também está disponível.

Serializar para JSON formatado

Para estruturar a saída JSON, defina JsonSerializerOptions.WriteIndented como true:

using System.Text.Json;

namespace SerializeWriteIndented
{
    public class WeatherForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
    }

    public class Program
    {
        public static void Main()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot"
            };

            var options = new JsonSerializerOptions { WriteIndented = true };
            string jsonString = JsonSerializer.Serialize(weatherForecast, options);

            Console.WriteLine(jsonString);
        }
    }
}
// output:
//{
//  "Date": "2019-08-01T00:00:00-07:00",
//  "TemperatureCelsius": 25,
//  "Summary": "Hot"
//}
Dim options As JsonSerializerOptions = New JsonSerializerOptions With {
    .WriteIndented = True
}
jsonString = JsonSerializer.Serialize(weatherForecast, options)

A partir do .NET 9, você também pode personalizar o caractere e o tamanho do recuo usando IndentCharacter e IndentSize.

Dica

Se você usar JsonSerializerOptions repetidamente com as mesmas opções, não crie uma instância JsonSerializerOptions sempre que a usar. Reutilize a mesma instância para cada chamada. Para mais informações, confira Reutilizar instâncias de JsonSerializerOptions.

Usar o GitHub Copilot para serializar para JSON

Você pode usar o GitHub Copilot em seu IDE para gerar código que usa System.Text.Json para serializar para JSON.

Se você estiver usando o Visual Studio 2022 versão 17.8 ou posterior, poderá experimentar o GitHub Copilot no Visual Studio orientado por IA para gerar código que usa System.Text.Json para serializar para JSON. Envie sua pergunta como um prompt na janela de bate-papo do Copilot, como no exemplo a seguir. Você também pode enviar prompts usando o bate-papo em linha na própria janela do editor.

Observação

O GitHub Copilot é alimentado por IA, portanto é passível de surpresas e erros. Verifique qualquer código gerado ou sugestões. Para obter mais informações sobre o uso geral do GitHub Copilot, o impacto do produto, a supervisão humana e a privacidade, consulte Perguntas frequentes sobre o GitHub Copilot.

O texto a seguir mostra um exemplo de prompt para o Copilot Chat:

Gere o código para usar System.Text.Json para serializar um objeto em uma cadeia de caracteres JSON. O objeto contém os seguintes campos: FirstName (string), Lastname (string), Age (int). Forneça um exemplo de saída.

Você pode personalizar o prompt para usar campos de objeto que atendam às suas necessidades.

Você pode usar recursos de bate-papo, como comandos de barra, referências a arquivos, métodos ou classes e threads, para definir a intenção e obter melhores respostas com o contexto com escopo. Para uma classe existente em um projeto que está aberto no IDE, você pode solicitar o GitHub Copilot com /generate code to serialize #Classname in #Filename to JSON.

A saída a seguir mostra um exemplo de resposta do Copilot Chat:

Sure! Below is an example of how to use System.Text.Json to serialize an object with the specified fields to a JSON string in C#:

using System;
using System.Text.Json;

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
}

public class Program
{
    public static void Main()
    {
        var person = new Person
        {
            FirstName = "John",
            LastName = "Doe",
            Age = 30
        };

        string jsonString = JsonSerializer.Serialize(person);
        Console.WriteLine(jsonString);
    }
}

**Example Output**
{"FirstName":"John","LastName":"Doe","Age":30}

This code defines a `Person` class, creates an instance of it, and then serializes it to a JSON string using `JsonSerializer.Serialize`. The resulting JSON string is then printed to the console.

Quando o Copilot retorna um bloco de código, a resposta inclui opções para copiar o código, inserir o código em um novo arquivo ou visualizar a saída do código.

Observação

Seus resultados podem ser diferentes do que é mostrado nas respostas de exemplo. Os modelos de IA não são determinísticos, ou seja, eles podem retornar respostas diferentes quando fazem a mesma pergunta. Isso pode ser devido a aprendizado e adaptação adicionais ao longo do tempo, variação de idioma, mudanças no contexto, como seu histórico de bate-papo e muito mais.

Captura de tela animada que mostra o uso do GitHub Copilot Chat no Visual Studio para serializar um objeto em uma cadeia de caracteres JSON.

Para saber mais, veja: