Partager via


Comment personnaliser les noms et valeurs de propriétés avec System.Text.Json

Par défaut, les noms de propriétés et les clés de dictionnaire sont inchangés dans la sortie JSON, y compris la casse. Les valeurs d’énumération sont représentées sous forme de nombres. De plus, les propriétés sont sérialisées dans l’ordre dans lequel elles sont définies. Vous pouvez toutefois personnaliser ces comportements en :

  • Spécifiant des noms de propriétés sérialisées spécifiques.
  • Utilisant une stratégie d’attribution de noms intégrée, telle que les mots en casse mixte (camelCase), les mots séparés par des caractères de soulignement (snake_case) ou par des tirets (kebab-case), pour les noms de propriétés et les clés de dictionnaire.
  • Utilisant une stratégie d’attribution de noms personnalisée pour les noms de propriétés et les clés de dictionnaire.
  • Sérialisant les valeurs d’énumération sous forme de chaînes, avec ou sans stratégie d’attribution de noms.
  • Configurant l’ordre des propriétés sérialisées.

Remarque

La stratégie d’attribution de noms des valeurs web par défaut est la casse mixte.

Conseil

Vous pouvez utiliser l’assistance AI pour personnaliser les noms et les valeurs des propriétés avec GitHub Copilot.

Pour les autres scénarios qui nécessitent une gestion spéciale des noms et des valeurs de propriétés JSON, vous pouvez implémenter des convertisseurs personnalisés.

Personnaliser les noms de propriétés individuelles

Pour définir le nom de propriétés individuelles, utilisez l’attribut [JsonPropertyName].

Voici un exemple de type à sérialiser et de JSON résultant :

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
}

Nom de propriété défini par cet attribut :

Utiliser une stratégie d’attribution de noms intégrée

Le tableau ci-dessous montre les stratégies d’attribution de noms intégrées et leur impact sur les noms de propriétés.

Stratégie d’affectation de noms Description Nom de propriété d’origine Nom de propriété converti
CamelCase Le premier mot commence par un caractère minuscule.
Les mots successifs commencent par un caractère majuscule.
TempCelsius tempCelsius
KebabCaseLower* Les mots sont séparés par des tirets.
Tous les caractères sont minuscules.
TempCelsius temp-celsius
KebabCaseUpper* Les mots sont séparés par des tirets.
Tous les caractères sont majuscules.
TempCelsius TEMP-CELSIUS
SnakeCaseLower* Les mots sont séparés par des traits de soulignement.
Tous les caractères sont minuscules.
TempCelsius temp_celsius
SnakeCaseUpper* Les mots sont séparés par des traits de soulignement.
Tous les caractères sont majuscules.
TempCelsius TEMP_CELSIUS

* Disponible dans .NET 8 et versions ultérieures.

L’exemple ci-dessous montre comment utiliser la casse mixte pour tous les noms de propriétés JSON en définissant JsonSerializerOptions.PropertyNamingPolicy sur 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)

Voici un exemple de classe à sérialiser et une sortie 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 stratégie d’attribution de noms :

  • S’applique à la sérialisation et à la désérialisation.
  • Est remplacé par des attributs [JsonPropertyName]. C’est pourquoi le nom de propriété JSON Wind dans l’exemple n’est pas en casse mixte.

Remarque

Aucune des stratégies d’attribution de noms intégrées ne prend en charge les lettres qui sont des paires de substitution. Pour plus d’informations, consultez le problème dotnet/runtime 90352.

Utiliser une stratégie de nommage de propriétés JSON personnalisée

Pour utiliser une stratégie de nommage de propriétés JSON personnalisée, créez une classe qui dérive de JsonNamingPolicy et remplace la méthode ConvertName, comme indiqué dans l’exemple suivant :

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

Définissez ensuite la propriété JsonSerializerOptions.PropertyNamingPolicy sur une instance de votre classe de stratégie d’affectation de noms :

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)

Voici un exemple de classe à sérialiser et une sortie 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
}

Stratégie de nommage de propriétés JSON :

  • S’applique à la sérialisation et à la désérialisation.
  • Est remplacé par des attributs [JsonPropertyName]. C’est pourquoi le nom de propriété JSON Wind dans l’exemple n’est pas en majuscules.

Utiliser une stratégie d’attribution de noms pour les clés de dictionnaire

Si une propriété d’un objet à sérialiser est de type Dictionary<string,TValue>, les clés string peuvent être converties à l’aide d’une stratégie d’attribution de noms (casse mixte, par exemple). Pour ce faire, définissez JsonSerializerOptions.DictionaryKeyPolicy votre stratégie d’attribution de noms souhaitée. L’exemple suivant utilise la stratégie d’attribution de noms 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)

Sérialiser un objet avec un dictionnaire nommé TemperatureRanges qui a des paires clé-valeur "ColdMinTemp", 20 et "HotMinTemp", 40 entraînerait une sortie JSON semblable à l’exemple suivant :

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

Les stratégies d’attribution de noms pour les clés de dictionnaire s’appliquent uniquement à la sérialisation. Si vous désérialisez un dictionnaire, les clés correspondent au fichier JSON même si vous définissez JsonSerializerOptions.DictionaryKeyPolicy sur une stratégie d’attribution de noms autre que par défaut.

Énumérations sous forme de chaînes

Par défaut, les énumérations sont sérialisées en tant que nombres. Pour sérialiser des noms d’énumération sous forme de chaînes, utilisez le convertisseur JsonStringEnumConverter ou JsonStringEnumConverter<TEnum>. Seul JsonStringEnumConverter<TEnum> est pris en charge par le runtime AOT natif.

Par défaut, les énumérations sont sérialisées en tant que nombres. Pour sérialiser des noms d’énumération sous forme de chaînes, utilisez le convertisseur JsonStringEnumConverter.

Par exemple, supposons que vous deviez sérialiser la classe suivante qui a une énumération :

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 le résumé est Hot, par défaut, le JSON sérialisé a la valeur numérique 3 :

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

L’exemple de code suivant sérialise les noms d’énumération au lieu des valeurs numériques et convertit les noms en casse mixte :

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)

Le JSON obtenu ressemble à l’exemple suivant :

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

Le composant intégré JsonStringEnumConverter peut également désérialiser les valeurs de chaîne. Il fonctionne avec ou sans stratégie d’attribution de noms spécifiée. L’exemple suivant illustre la désérialisation à l’aide de 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)

Vous pouvez également spécifier le convertisseur à utiliser en annotant votre énumération avec JsonConverterAttribute. L’exemple ci-dessous montre comment spécifier JsonStringEnumConverter<TEnum> (disponible dans .NET 8 et versions ultérieures) à l’aide de l’attribut JsonConverterAttribute. Par exemple, supposons que vous deviez sérialiser la classe suivante qui a une énumération :

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
}

L’exemple de code suivant sérialise les noms d’énumération au lieu des valeurs numériques :

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

Le JSON obtenu ressemble à l’exemple suivant :

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

Pour utiliser le convertisseur avec la génération de source, consultez la section Sérialiser les champs d’énumération sous forme de chaînes.

Configurer l’ordre des propriétés sérialisées

Par défaut, les propriétés sont sérialisées dans l’ordre dans lequel elles sont définies dans leur classe. L’attribut [JsonPropertyOrder] vous permet de spécifier l’ordre des propriétés dans la sortie JSON de la sérialisation. La valeur par défaut de la propriété Order est zéro. Définissez Order sur un nombre positif pour positionner une propriété après celles qui ont la valeur par défaut. Une valeur négative Order positionne une propriété avant celles qui ont la valeur par défaut. Les propriétés sont écrites dans l’ordre, de la valeur Order la plus faible à la plus élevée. Voici un exemple :

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

Utilisez GitHub Copilot pour personnaliser les noms et l’ordre des propriétés

Vous pouvez utiliser GitHub Copilot dans votre IDE pour générer du code permettant de personnaliser les noms et l’ordre des propriétés sérialisées.

Si vous utilisez Visual Studio 2022 version 17.8 ou une version ultérieure, vous pouvez essayer le GitHub Copilot piloté par l’IA dans Visual Studio pour générer du code qui utilise System.Text.Json pour personnaliser les noms et l’ordre des propriétés dans la sortie JSON de la sérialisation. Soumettez votre question sous forme de requête dans la fenêtre de discussion de Copilot, comme dans l’exemple suivant. Vous pouvez également soumettre des requêtes en utilisant le chat en ligne dans la fenêtre de l’éditeur elle-même.

Remarque

GitHub Copilot est alimenté par l’IA, donc des surprises et des erreurs sont possibles. Assurez-vous de vérifier tout code ou suggestion généré. Pour plus d’informations sur l’utilisation générale de GitHub Copilot, l’impact du produit, la supervision humaine et la confidentialité, veuillez consulter FAQ GitHub Copilot.

L’exemple suivant montre comment utiliser Copilot pour modifier du code existant afin de personnaliser les noms et l’ordre des propriétés lors de la sérialisation en JSON.

  1. Ajoutez l’exemple de code C# suivant dans un fichier de code Example.cs dans votre éditeur. Dans Visual Studio, vous pouvez utiliser un projet d’application console C# pour essayer cet exemple.

    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 le code fait ce qui suit :

    • Crée une instance de la classe Person et initialise ses propriétés avec des valeurs.
    • Sérialise l’objet person en une chaîne JSON en utilisant JsonSerializer.Serialize.
    • Affiche la chaîne JSON suivante dans la console :
    {"FirstName":"John","LastName":"Doe","Age":30,"Country":"USA"}
    
  2. Dans Copilot Chat, entrez l’invite suivante pour modifier le code afin de personnaliser les noms et l’ordre de la sortie de la sérialisation JSON.

    #Example.cs modifiez le code pour utiliser System.Text.Json afin de personnaliser les noms des propriétés et l’ordre de la sortie JSON de la sérialisation. Définissez les noms des propriétés : FirstName en first_name, LastName en last_name. Définissez l’ordre comme suit : Country, FirstName, LastName, Age. Fournissez une sortie de sérialisation personnalisée.

    #Example.cs dans l’invite fournit une référence de fichier en tant que contexte à Copilot. Vous pouvez personnaliser l’invite pour produire une chaîne JSON avec des noms de propriétés et des valeurs qui correspondent à vos besoins. Pour définir l’intention et obtenir de meilleures réponses avec un contexte défini, vous pouvez utiliser des fonctionnalités de chat telles que les commandes slash, les références aux fichiers, méthodes ou classes, et les threads.

    Voici un exemple de réponse du chat Copilot :

    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.
    

Lorsque Copilot retourne un bloc de code, la réponse inclut des options pour copier le code, insérer le code dans un nouveau fichier, ou prévisualiser la sortie du code.

Remarque

Vos résultats peuvent être différents de ce qui est montré dans les réponses d’exemple. Les modèles IA sont non déterministes, ce qui signifie qu’ils peuvent renvoyer des réponses différentes lorsqu’on leur pose la même question. Cela peut être dû à un apprentissage et à une adaptation supplémentaires au fil du temps, à une variation de la langue, à des changements de contexte, tels que l’historique de votre chat, et plus encore.

Voir aussi