Como personalizar nomes e valores de propriedade com System.Text.Json

Por padrão, os nomes de propriedade e as chaves de dicionário permanecem inalterados na saída JSON, incluindo maiúsculas e minúsculas. Os valores de enum são representados como números. E as propriedades são serializadas na ordem em que são definidas. No entanto, você pode personalizar esses comportamentos:

  • Especificando propriedades serializadas específicas e nomes de membros enum.
  • Usando uma política de nomenclatura interna, como camelCase, snake_case ou kebab-case, para nomes de propriedade e chaves de dicionário.
  • Usando uma política de nomenclatura personalizada para nomes de propriedade e chaves de dicionário.
  • Serialização de valores de enum como cadeias de caracteres, com ou sem uma política de nomenclatura.
  • Configurando a ordem das propriedades serializadas.

Nota

A política de nomenclatura padrão da Web é camel case.

Gorjeta

Você pode usar a assistência de IA para personalizar nomes e valores de propriedade com o GitHub Copilot.

Para outros cenários que exigem tratamento especial de nomes e valores de propriedade JSON, você pode implementar conversores personalizados.

Personalizar nomes de propriedades individuais

Para definir o nome de propriedades individuais, use o atributo [JsonPropertyName].

Aqui está um tipo de exemplo para serializar e JSON resultante:

public class WeatherForecastWithPropertyName
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
    [JsonPropertyName("Wind")]
    public int WindSpeed { get; set; }
}
Public Class WeatherForecastWithPropertyName
    Public Property [Date] As DateTimeOffset
    Public Property TemperatureCelsius As Integer
    Public Property Summary As String

    <JsonPropertyName("Wind")>
    Public Property WindSpeed As Integer

End Class
{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "Hot",
  "Wind": 35
}

O nome da propriedade definido por este atributo:

Usar uma política de nomenclatura interna

A tabela a seguir mostra as políticas de nomenclatura internas e como elas afetam os nomes de propriedade.

Política de nomenclatura Description Nome do imóvel original Nome da propriedade convertida
CamelCase A primeira palavra começa com um caractere minúsculo.
Palavras sucessivas começam com um caractere maiúsculo.
TempCelsius tempCelsius
KebabCaseLower* As palavras são separadas por hífenes.
Todos os caracteres são minúsculos.
TempCelsius temp-celsius
KebabCaseUpper* As palavras são separadas por hífenes.
Todos os caracteres são maiúsculos.
TempCelsius TEMP-CELSIUS
SnakeCaseLower* As palavras são separadas por sublinhados.
Todos os caracteres são minúsculos.
TempCelsius temp_celsius
SnakeCaseUpper* As palavras são separadas por sublinhados.
Todos os caracteres são maiúsculos.
TempCelsius TEMP_CELSIUS

* Disponível em .NET 8 e versões posteriores.

O exemplo a seguir mostra como usar camel case para todos os nomes de propriedade JSON definindo JsonSerializerOptions.PropertyNamingPolicy como JsonNamingPolicy.CamelCase:

var serializeOptions = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, serializeOptions);
Dim serializeOptions As JsonSerializerOptions = New JsonSerializerOptions With {
    .PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    .WriteIndented = True
}
jsonString = JsonSerializer.Serialize(weatherForecast, serializeOptions)

Aqui está uma classe de exemplo para serializar e saída JSON:

public class WeatherForecastWithPropertyName
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
    [JsonPropertyName("Wind")]
    public int WindSpeed { get; set; }
}
Public Class WeatherForecastWithPropertyName
    Public Property [Date] As DateTimeOffset
    Public Property TemperatureCelsius As Integer
    Public Property Summary As String

    <JsonPropertyName("Wind")>
    Public Property WindSpeed As Integer

End Class
{
  "date": "2019-08-01T00:00:00-07:00",
  "temperatureCelsius": 25,
  "summary": "Hot",
  "Wind": 35
}

A política de nomenclatura:

  • Aplica-se à serialização e desserialização.
  • É substituído por [JsonPropertyName] atributos. É por isso que o nome Wind da propriedade JSON no exemplo não é camel case.

Nota

Nenhuma das políticas de nomenclatura incorporadas suporta letras que sejam pares substitutos. Para obter mais informações, consulte dotnet/runtime issue 90352.

Usar uma política de nomenclatura de propriedade JSON personalizada

Para usar uma política de JsonNamingPolicy nomenclatura de propriedade JSON personalizada, crie uma classe que derive e substitua o ConvertName método, conforme mostrado no exemplo a seguir:

using System.Text.Json;

namespace SystemTextJsonSamples
{
    public class UpperCaseNamingPolicy : JsonNamingPolicy
    {
        public override string ConvertName(string name) =>
            name.ToUpper();
    }
}
Imports System.Text.Json

Namespace SystemTextJsonSamples

    Public Class UpperCaseNamingPolicy
        Inherits JsonNamingPolicy

        Public Overrides Function ConvertName(name As String) As String
            Return name.ToUpper()
        End Function

    End Class

End Namespace

Em seguida, defina a JsonSerializerOptions.PropertyNamingPolicy propriedade como uma instância da sua classe de política de nomenclatura:

var options = new JsonSerializerOptions
{
    PropertyNamingPolicy = new UpperCaseNamingPolicy(),
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);
Dim options As JsonSerializerOptions = New JsonSerializerOptions With {
    .PropertyNamingPolicy = New UpperCaseNamingPolicy,
    .WriteIndented = True
}
jsonString = JsonSerializer.Serialize(weatherForecast1, options)

Aqui está uma classe de exemplo para serializar e saída JSON:

public class WeatherForecastWithPropertyName
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
    [JsonPropertyName("Wind")]
    public int WindSpeed { get; set; }
}
Public Class WeatherForecastWithPropertyName
    Public Property [Date] As DateTimeOffset
    Public Property TemperatureCelsius As Integer
    Public Property Summary As String

    <JsonPropertyName("Wind")>
    Public Property WindSpeed As Integer

End Class
{
  "DATE": "2019-08-01T00:00:00-07:00",
  "TEMPERATURECELSIUS": 25,
  "SUMMARY": "Hot",
  "Wind": 35
}

A política de nomenclatura da propriedade JSON:

  • Aplica-se à serialização e desserialização.
  • É substituído por [JsonPropertyName] atributos. É por isso que o nome Wind da propriedade JSON no exemplo não é maiúsculo.

Usar uma política de nomenclatura para chaves de dicionário

Se uma propriedade de um objeto a ser serializado for do tipo Dictionary<string,TValue>, as string chaves poderão ser convertidas usando uma política de nomenclatura, como camel case. Para fazer isso, defina JsonSerializerOptions.DictionaryKeyPolicy a política de nomenclatura desejada. O exemplo a seguir usa a CamelCase política de nomenclatura:

var options = new JsonSerializerOptions
{
    DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);
Dim options As JsonSerializerOptions = New JsonSerializerOptions With {
    .DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
    .WriteIndented = True
}
jsonString = JsonSerializer.Serialize(weatherForecast, options)

Serializar um objeto com um dicionário chamado TemperatureRanges que tem pares "ColdMinTemp", 20 chave-valor e "HotMinTemp", 40 resultaria em saída JSON como o exemplo a seguir:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "Hot",
  "TemperatureRanges": {
    "coldMinTemp": 20,
    "hotMinTemp": 40
  }
}

As políticas de nomenclatura para chaves de dicionário aplicam-se apenas à serialização. Se você desserializar um dicionário, as chaves corresponderão ao arquivo JSON, mesmo se você definir JsonSerializerOptions.DictionaryKeyPolicy como uma política de nomenclatura não padrão.

Enums como cordas

Por padrão, enums são serializados como números. Para serializar nomes de enum como strings, use o JsonStringEnumConverter conversor ou JsonStringEnumConverter<TEnum> . Somente JsonStringEnumConverter<TEnum> é suportado pelo tempo de execução nativo da AOT.

Por exemplo, suponha que você precise serializar a seguinte classe que tenha um enum:

public class WeatherForecastWithEnum
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public Summary? Summary { get; set; }
}

public enum Summary
{
    Cold, Cool, Warm, Hot
}
Public Class WeatherForecastWithEnum
    Public Property [Date] As DateTimeOffset
    Public Property TemperatureCelsius As Integer
    Public Property Summary As Summary
End Class

Public Enum Summary
    Cold
    Cool
    Warm
    Hot
End Enum

Se o Resumo for Hot, por padrão, o JSON serializado terá o valor numérico 3:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": 3
}

O código de exemplo a seguir serializa os nomes de enum em vez dos valores numéricos e converte os nomes em camel case:

options = new JsonSerializerOptions
{
    WriteIndented = true,
    Converters =
    {
        new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
    }
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);
options = New JsonSerializerOptions With {
    .WriteIndented = True
}
options.Converters.Add(New JsonStringEnumConverter(JsonNamingPolicy.CamelCase))
jsonString = JsonSerializer.Serialize(weatherForecast, options)

O JSON resultante se parece com o exemplo a seguir:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "hot"
}

O built-in JsonStringEnumConverter também pode desserializar valores de cadeia de caracteres. Ele funciona com ou sem uma política de nomenclatura especificada. O exemplo a seguir mostra a desserialização usando CamelCase:

options = new JsonSerializerOptions
{
    Converters =
    {
        new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
    }
};
weatherForecast = JsonSerializer.Deserialize<WeatherForecastWithEnum>(jsonString, options)!;
options = New JsonSerializerOptions
options.Converters.Add(New JsonStringEnumConverter(JsonNamingPolicy.CamelCase))
weatherForecast = JsonSerializer.Deserialize(Of WeatherForecastWithEnum)(jsonString, options)

JsonConverterAttribute

Você também pode especificar o conversor a ser usado anotando seu enum com JsonConverterAttribute. O exemplo a seguir mostra como especificar o JsonStringEnumConverter<TEnum> (disponível no .NET 8 e versões posteriores) usando o JsonConverterAttribute atributo. Por exemplo, suponha que você precise serializar a seguinte classe que tenha um enum:

public class WeatherForecastWithPrecipEnum
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public Precipitation? Precipitation { get; set; }
}

[JsonConverter(typeof(JsonStringEnumConverter<Precipitation>))]
public enum Precipitation
{
    Drizzle, Rain, Sleet, Hail, Snow
}

O código de exemplo a seguir serializa os nomes de enum em vez dos valores numéricos:

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

O JSON resultante tem esta aparência:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Precipitation": "Sleet"
}

Nomes de membros enum personalizados

A partir do .NET 9, você pode personalizar os nomes de membros individuais do enum para tipos que são serializados como cadeias de caracteres. Para personalizar um nome de membro enum, anote-o com o atributo JsonStringEnumMemberName.

Por exemplo, suponha que você precise serializar a seguinte classe que tenha um enum com um nome de membro personalizado:

public class WeatherForecastWithEnumCustomName
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public CloudCover? Sky { get; set; }
}

[JsonConverter(typeof(JsonStringEnumConverter))]
public enum CloudCover
{
    Clear,
    [JsonStringEnumMemberName("Partly cloudy")]
    Partial,
    Overcast
}

O código de exemplo a seguir serializa os nomes de enum em vez dos valores numéricos:

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

O JSON resultante tem esta aparência:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Sky": "Partly cloudy"
}

Geração de fontes

Para usar o conversor com geração de código-fonte, consulte Serializar campos enum como strings.

Configurar a ordem das propriedades serializadas

Por padrão, as propriedades são serializadas na ordem em que são definidas em sua classe. O [JsonPropertyOrder] atributo permite especificar a ordem das propriedades na saída JSON da serialização. O valor padrão da Order propriedade é zero. Defina Order como um número positivo para posicionar uma propriedade após aquelas que têm o valor padrão. Uma posição negativa Order uma propriedade antes daquelas que têm o valor padrão. As propriedades são escritas em ordem do menor Order valor para o mais alto. Eis um exemplo:

using System.Text.Json;
using System.Text.Json.Serialization;

namespace PropertyOrder
{
    public class WeatherForecast
    {
        [JsonPropertyOrder(-5)]
        public DateTime Date { get; set; }
        public int TemperatureC { get; set; }
        [JsonPropertyOrder(-2)]
        public int TemperatureF { get; set; }
        [JsonPropertyOrder(5)]
        public string? Summary { get; set; }
        [JsonPropertyOrder(2)]
        public int WindSpeed { get; set; }
    }

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

            var options = new JsonSerializerOptions { WriteIndented = true };
            string jsonString = JsonSerializer.Serialize(weatherForecast, options);
            Console.WriteLine(jsonString);
        }
    }
}
// output:
//{
//  "Date": "2019-08-01T00:00:00",
//  "TemperatureF": 25,
//  "TemperatureC": 25,
//  "WindSpeed": 10,
//  "Summary": "Hot"
//}

Use o Github Copilot para personalizar nomes e pedidos de propriedades

Você pode usar o GitHub Copilot em seu IDE para gerar código para personalizar nomes e ordem de propriedades serializadas.

Se você estiver usando o Visual Studio 2022 versão 17.8 ou posterior, poderá tentar o Copiloto GitHub controlado por IA no Visual Studio para gerar código que usa System.Text.Json para personalizar nomes de propriedade e ordem na saída JSON da serialização. 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 embutido na própria janela do editor.

Nota

O GitHub Copilot é alimentado por IA, então surpresas e erros são possíveis. Certifique-se de verificar qualquer código gerado ou sugestões. Para obter mais informações sobre o uso geral do GitHub Copilot, impacto no produto, supervisão humana e privacidade, consulte Perguntas frequentes sobre o GitHub Copilot.

O exemplo a seguir mostra como usar o Copilot para modificar o código existente para personalizar nomes de propriedade e ordem ao serializar para JSON.

  1. Adicione o seguinte código de exemplo C# a um arquivo Example.cs de código em seu editor. No Visual Studio, você pode usar um projeto de aplicativo de console C# para tentar este exemplo.

    using System.Text.Json;
    
    public class Person
    {
        public string? FirstName { get; set; }
        public string? LastName { get; set; }
        public int Age { get; set; }
        public string? Country { get; set; }
    }
    
    public class Program
    {
        public static void Main()
        {
            var person = new Person
            {
                FirstName = "John",
                LastName = "Doe",
                Age = 30,
                Country = "USA"
            };
    
            string jsonString = JsonSerializer.Serialize(person);
            Console.WriteLine(jsonString);
        }
    }
    

    Example.cs code faz o seguinte:

    • Cria uma instância da Person classe e inicializa suas propriedades com valores.
    • Serializa o person objeto para uma cadeia de caracteres JSON usando JsonSerializer.Serialize.
    • Imprime a seguinte cadeia de caracteres JSON no console:
    {"FirstName":"John","LastName":"Doe","Age":30,"Country":"USA"}
    
  2. No Copilot Chat, insira o seguinte prompt para modificar o código para personalizar nomes e a ordem da saída de serialização JSON.

    #Example.cs modificar o código a ser usado System.Text.Json para personalizar nomes de propriedade e a ordem da saída JSON da serialização. Defina nomes de propriedade: FirstName como first_name, LastName como last_name. Defina a ordem para: País, Nome, Sobrenome, Idade. Forneça saída de serialização personalizada.

    #Example.cs no prompt fornece uma referência de arquivo como contexto para Copilot. Você pode personalizar o prompt para gerar uma cadeia de caracteres JSON com nomes de propriedade e valores que atendam às suas necessidades. Para definir a intenção e obter melhores respostas com contexto de escopo, você pode usar recursos de bate-papo, como comandos de barra, referências a arquivos, métodos ou classes e threads.

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

    To customize the property names and order of the JSON output using System.Text.Json, you can use the JsonPropertyName attribute to rename properties and the JsonPropertyOrder attribute to set the order. Here's how you can modify your code:
    
    using System.Text.Json;
    using System.Text.Json.Serialization;
    
    public class Person
    {
        [JsonPropertyName("first_name")]
        [JsonPropertyOrder(2)]
        public string? FirstName { get; set; }
    
        [JsonPropertyName("last_name")]
        [JsonPropertyOrder(3)]
        public string? LastName { get; set; }
    
        [JsonPropertyOrder(4)]
        public int Age { get; set; }
    
        [JsonPropertyOrder(1)]
        public string? Country { get; set; }
    }
    
    public class Program
    {
        public static void Main()
        {
            var person = new Person
            {
                FirstName = "John",
                LastName = "Doe",
                Age = 30,
                Country = "USA"
            };
    
            string jsonString = JsonSerializer.Serialize(person, new JsonSerializerOptions { WriteIndented = true });
            Console.WriteLine(jsonString);
        }
    }
    
    **Explanation:**
    
    1. Renaming Properties: The JsonPropertyName attribute is used to rename FirstName to first_name and LastName to last_name.
    2. Ordering Properties: The JsonPropertyOrder attribute is used to set the order of the properties in the JSON output. The order is set as:
       • Country (Order 1)
       • FirstName (Order 2)
       • LastName (Order 3)
       • Age (Order 4)
    3. Indented JSON: The JsonSerializerOptions with WriteIndented = true is used to make the JSON output more readable.
    
    **Customized Serialization Output:**
    {
      "Country": "USA",
      "first_name": "John",
      "last_name": "Doe",
      "Age": 30
    }
    
    This ensures that the JSON output has the customized property names and the specified order.
    

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.

Nota

Seus resultados podem ser diferentes do que é mostrado nas respostas de exemplo. Os modelos de IA não são determinísticos, o que significa que podem retornar respostas diferentes quando feitas 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.

Consulte também