Compartir a través de


Personalización de los nombres y valores de propiedades con System.Text.Json

De forma predeterminada, los nombres de propiedad y las claves de diccionario no se modifican en la salida JSON, ni siquiera el uso de mayúsculas y minúsculas. Los valores de enumeración se representan como números. Y las propiedades se serializan en el orden en que se definen. Sin embargo, puede personalizar estos comportamientos mediante:

  • Especificar nombres de propiedad serializados específicos.
  • Con una directiva de nomenclatura integrada, como camelCase, snake_case o kebab-case, para nombres de propiedad y claves de diccionario.
  • Usar una directiva de nomenclatura personalizada para los nombres de las propiedades y las claves del diccionario.
  • Serializar valores de enumeración como cadenas, con o sin una directiva de nomenclatura.
  • Configuración del orden de las propiedades serializadas.

Nota:

La directiva de nomenclatura web predeterminada es el caso camel.

Sugerencia

Puede usar la asistencia de IA para personalizar los nombres y valores de propiedades con GitHub Copilot.

En el caso de otros escenarios que requieran un tratamiento especial de los nombres y valores de propiedades JSON, puede implementar convertidores personalizados.

Personalizar nombres de propiedades individuales

Para establecer el nombre de propiedades individuales, use el atributo [JsonPropertyName].

Aquí se muestra un tipo de ejemplo que se serializa y el 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
}

Nombre de propiedad establecido por este atributo:

Uso de una directiva de nomenclatura integrada

En la tabla siguiente se muestran las directivas de nomenclatura integradas y cómo afectan a los nombres de propiedad.

Directiva de nomenclatura Descripción Nombre de propiedad original Nombre de propiedad convertido
CamelCase La primera palabra comienza con un carácter en minúsculas.
Las palabras sucesivas comienzan con un carácter en mayúsculas.
TempCelsius tempCelsius
KebabCaseLower* Las palabras están separadas por guiones.
Todos los caracteres están en minúsculas.
TempCelsius temp-celsius
KebabCaseUpper* Las palabras están separadas por guiones.
Todos los caracteres están en mayúsculas.
TempCelsius TEMP-CELSIUS
SnakeCaseLower* Las palabras están separadas por caracteres de subrayado.
Todos los caracteres están en minúsculas.
TempCelsius temp_celsius
SnakeCaseUpper* Las palabras están separadas por caracteres de subrayado.
Todos los caracteres están en mayúsculas.
TempCelsius TEMP_CELSIUS

* Disponible en .NET 8 y versiones posteriores.

El ejemplo siguiente se muestra cómo utilizar el caso camel para todos los nombres de propiedad JSON mediante el establecimiento de JsonSerializerOptions.PropertyNamingPolicy a 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)

Aquí se muestra una clase de ejemplo que se serializa y la salida 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
}

La directiva de nomenclatura:

  • Se aplica a la serialización y la deserialización.
  • Se invalida con atributos [JsonPropertyName]. Este es el motivo por el que el nombre de la propiedad JSON Wind del ejemplo no usa mayúsculas y minúsculas combinadas Camel.

Nota:

Ninguna de las directivas de nomenclatura integradas admite letras que son pares suplentes. Para obtener más información, consulte problema dotnet/runtime 90352.

Uso de una directiva de nomenclatura de propiedades JSON personalizada

Para usar una directiva de nomenclatura de propiedades JSON personalizada, cree una clase que derive de JsonNamingPolicy e invalide el método ConvertName, tal y como se muestra en el ejemplo siguiente:

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

Establezca luego la propiedad JsonSerializerOptions.PropertyNamingPolicy en una instancia de la clase de directiva 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)

Aquí se muestra una clase de ejemplo que se serializa y la salida 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
}

La directiva de nomenclatura de propiedades JSON personalizada:

  • Se aplica a la serialización y la deserialización.
  • Se invalida con atributos [JsonPropertyName]. Este es el motivo por el que el nombre de la propiedad JSON Wind del ejemplo no usa mayúsculas.

Usar una directiva de nomenclatura para las claves de diccionario

Si una propiedad de un objeto a serializar es de tipo Dictionary<string,TValue>, las claves string se pueden convertir usando una directiva de nomenclatura, como el caso camel. Para ello, establezca en JsonSerializerOptions.DictionaryKeyPolicy la directiva de nomenclatura deseada. En el ejemplo siguiente se usa la directiva de nomenclatura CamelCase :

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)

La serialización de un objeto con un diccionario denominado TemperatureRanges que tenga pares clave-valor "ColdMinTemp", 20 y "HotMinTemp", 40 se traduciría en una salida JSON similar a la del ejemplo siguiente:

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

Las directivas de nomenclatura de las claves de diccionario solo se aplican a la serialización. Si deserializa un diccionario, las claves coincidirán con el archivo JSON aunque se establezca JsonSerializerOptions.DictionaryKeyPolicy en una directiva de nomenclatura no predeterminada.

Enumeraciones como cadenas

De forma predeterminada, las enumeraciones se serializan como números. Para serializar nombres de enumeración como cadenas, use el convertidor de JsonStringEnumConverter o JsonStringEnumConverter<TEnum>. Solo JsonStringEnumConverter<TEnum> es compatible con el entorno runtime de AOT nativo.

De forma predeterminada, las enumeraciones se serializan como números. Para serializar nombres de enumeración como cadenas, use el convertidor de JsonStringEnumConverter.

Por ejemplo, supongamos que hay que serializar la siguiente clase que tiene una enumeración:

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

Si el resumen es Hot, el JSON serializado tiene el valor numérico 3 de forma predeterminada:

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

En el código de ejemplo siguiente se serializan los nombres de enumeración en lugar de los valores numéricos y los nombres se convierten en mayúsculas y minúsculas combinadas Camel:

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)

El JSON resultante tendrá un aspecto similar al siguiente:

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

El elemento integrado JsonStringEnumConverter también puede deserializar los valores de cadena. Funciona con o sin una directiva de nomenclatura especificada. En el ejemplo siguiente se muestra la deserialización mediante 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)

También puede especificar el convertidor que se va a usar anotando la enumeración con JsonConverterAttribute. En el ejemplo siguiente se muestra cómo especificar JsonStringEnumConverter<TEnum>(disponible en .NET 8 y versiones posteriores) mediante el atributoJsonConverterAttribute. Por ejemplo, supongamos que hay que serializar la siguiente clase que tiene una enumeración:

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
}

El código de ejemplo siguiente serializa los nombres de enumeración en lugar de los valores numéricos:

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

El JSON resultante tendrá un aspecto similar al siguiente:

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

Para usar el convertidor con generación de origen, consulte Serializar campos de enumeración como cadenas.

Configurar el orden de las propiedades serializadas

De forma predeterminada, las propiedades se serializan en el orden en que se definen en su clase. El atributo [JsonPropertyOrder] permite especificar el orden de las propiedades en la salida JSON de la serialización. El valor predeterminado de la propiedad Order es cero. Se establece Order en un número positivo para colocar una propiedad detrás de las que tienen el valor predeterminado. Un valor negativo Order coloca una propiedad delante de las que tienen el valor predeterminado. Las propiedades se escriben por orden, del valor Order más bajo al más alto. Este es un ejemplo:

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"
//}

Usar Github Copilot para personalizar nombres y orden de propiedades

Puede usar GitHub Copilot en el IDE para generar código para personalizar los nombres y el orden de las propiedades serializadas.

Si usa la versión 17.8 o posterior de Visual Studio 2022, puede probar GitHub Copilot controlado por IA en Visual Studio para generar código que se usa System.Text.Json para personalizar los nombres y el orden de propiedades en el resultado JSON de la serialización. Envíe su pregunta como solicitud en la ventana de chat de Copilot, como en el ejemplo siguiente. También puede enviar mensajes mediante el chat en línea en la propia ventana del editor.

Nota:

GitHub Copilot funciona con IA, por lo que es posible que se produzcan sorpresas y errores. Asegúrese de comprobar cualquier código o sugerencia generado. Para obtener más información sobre el uso general de GitHub Copilot, impacto en el producto, supervisión humana y privacidad, consulte Preguntas más frecuentes sobre GitHub Copilot.

En el ejemplo siguiente se ve cómo usar Copilot para modificar el código existente para personalizar los nombres y le orden de las propiedades al serializar en JSON.

  1. Agregue el siguiente código de C# de ejemplo a un archivo de código Example.cs en el editor. En Visual Studio, puede usar un proyecto de aplicación de consola de C# para probar este ejemplo.

    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);
        }
    }
    

    El código Example.cs hace lo siguiente:

    • Crea una instancia de la clase Person e inicializa sus propiedades con valores.
    • Serializa el objeto person en una cadena JSON mediante JsonSerializer.Serialize.
    • Imprime la siguiente cadena JSON en la consola:
    {"FirstName":"John","LastName":"Doe","Age":30,"Country":"USA"}
    
  2. En Copilot Chat, introduzca la siguiente solicitud para modificar el código para personalizar los nombres y el orden del resultado de serialización de JSON.

    #Example.cs modifica el código que se va a usar System.Text.Json para personalizar los nombres y le orden de las propiedades del resultado JSON de la serialización. Cree los nombres de propiedad: FirstName to first_name, LastName to last_name. Fije el orden en: Country, FirstName, LastName, Age. Indique el resultado de serialización personalizado.

    #Example.cs en el símbolo del sistema genera una referencia de archivo como contexto en Copilot. Puede personalizar la solicitud para generar una cadena JSON con nombres y valores de propiedad que se adapten a sus requisitos. Para generar intención y obtener mejores respuestas con contexto con ámbito, puede usar funciones de chat, como comandos de barra diagonal, referencias a archivos, métodos, clases y subprocesos.

    En la salida siguiente se muestra un ejemplo de respuesta de 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.
    

Cuando Copilot devuelve un bloque de código, la respuesta incluye opciones para copiar el código, insertar el código en un nuevo archivo u obtener una vista previa de la salida del código.

Nota:

Los resultados pueden ser diferentes de lo que se muestra en las respuestas de ejemplo. Los modelos de IA no son deterministas, lo que significa que pueden devolver respuestas diferentes cuando se le haga la misma pregunta. Esto puede deberse al aprendizaje y la adaptación adicionales a lo largo del tiempo, la variación del lenguaje, los cambios en el contexto, como el historial de chat, etc.

Consulte también