Maison >développement back-end >C++ >Comment spécifier des noms personnalisés pour les valeurs Enum dans System.Text.Json ?

Comment spécifier des noms personnalisés pour les valeurs Enum dans System.Text.Json ?

DDD
DDDoriginal
2025-01-14 10:37:43329parcourir

How to Specify Custom Names for Enum Values in System.Text.Json?

System.Text.Json : Comment spécifier un nom personnalisé pour une valeur d'énumération ?

Cette fonctionnalité n'est pas disponible hors de dans .NET Core 3.0, .NET 5, .NET 6.0, .NET 7.0 ou .NET 8.0. Par conséquent, vous devrez créer votre propre JsonConverterFactory qui sérialise les énumérations avec des noms de valeurs personnalisés spécifiés par les attributs, ou utiliser un package NuGet qui fait de même, tel que Macross.Json.Extensions.

Si vous travaillez dans .NET 7 ou version ultérieure, ou il suffit de sérialiser mais pas de désérialiser les énumérations avec des noms personnalisés dans les versions antérieures, les noms personnalisés peuvent être facilement pris en charge en créant un JsonConverterFactory qui adapte JsonStringEnumConverter en construisant un JsonNamingPolicy personnalisé pour chaque énumération avec [EnumMember(Value = "xxx")] appliqué à n'importe quelle valeur d'énumération.

Voici les étapes impliquées :

  1. Créer une personnalisation convertisseur :
public class JsonEnumMemberStringEnumConverter : JsonConverterFactory
{
    public JsonEnumMemberStringEnumConverter() : this(null, true) { }

    public JsonEnumMemberStringEnumConverter(JsonNamingPolicy? namingPolicy = null, bool allowIntegerValues = true)
    {
        this.namingPolicy = namingPolicy;
        this.allowIntegerValues = allowIntegerValues;
        this.baseConverter = new JsonStringEnumConverter(namingPolicy, allowIntegerValues);
    }

    public override bool CanConvert(Type typeToConvert) => baseConverter.CanConvert(typeToConvert);

    public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
    {
        var query = from field in typeToConvert.GetFields(BindingFlags.Public | BindingFlags.Static)
                    let attr = field.GetCustomAttribute<EnumMemberAttribute>()
                    where attr != null &amp;&amp; attr.Value != null
                    select (field.Name, attr.Value);
        var dictionary = query.ToDictionary(p => p.Item1, p => p.Item2);
        if (dictionary.Count > 0)
            return new JsonStringEnumConverter(new DictionaryLookupNamingPolicy(dictionary, namingPolicy), allowIntegerValues).CreateConverter(typeToConvert, options);
        else
            return baseConverter.CreateConverter(typeToConvert, options);
    }
}

public class JsonNamingPolicyDecorator : JsonNamingPolicy
{
    readonly JsonNamingPolicy? underlyingNamingPolicy;

    public JsonNamingPolicyDecorator(JsonNamingPolicy? underlyingNamingPolicy) => this.underlyingNamingPolicy = underlyingNamingPolicy;
    public override string ConvertName(string name) => underlyingNamingPolicy?.ConvertName(name) ?? name;
}

internal class DictionaryLookupNamingPolicy : JsonNamingPolicyDecorator
{
    readonly Dictionary<string, string> dictionary;

    public DictionaryLookupNamingPolicy(Dictionary<string, string> dictionary, JsonNamingPolicy? underlyingNamingPolicy) : base(underlyingNamingPolicy) => this.dictionary = dictionary ?? throw new ArgumentNullException();
    public override string ConvertName(string name) => dictionary.TryGetValue(name, out var value) ? value : base.ConvertName(name);
}
  1. Décorez votre énumération :
public enum Example
{
    Trick,
    Treat,
    [EnumMember(Value = "Trick-Or-Treat")]
    TrickOrTreat,
}
  1. Utilisez le convertisseur autonome :
var options = new JsonSerializerOptions
{
    Converters = { new JsonEnumMemberStringEnumConverter() },
    // Set other options as required:
    WriteIndented = true,
};
var json = JsonSerializer.Serialize(values, options);
  1. Enregistrez le convertisseur avec ASP.NET Core :

Reportez-vous à la réponse à cette question question de Mani Gandham pour obtenir des conseils sur la façon de procéder ceci.

Remarques :

  • Dans .NET 6 et versions antérieures, JsonStringEnumConverter ignore sa politique de dénomination lors de la désérialisation ; ce problème a été résolu dans la pull request 73348.
  • Dans .Net Core 3.x, le convertisseur peut ne pas fonctionner comme souhaité avec les énumérations [Flags]. Ce problème a été résolu dans le problème n° 31622 dans .NET 5.
  • Si vous devez effectuer un aller-retour dans une énumération avec des noms de valeurs personnalisés dans .NET 6 ou une version antérieure, vous devrez créer une fabrique de convertisseurs générique à partir de scratch.
  • Une solution alternative consiste à utiliser JsonStringEnumMemberConverter du package Macross.Json.Extensions. Installez le package, puis décorez votre énumération avec l'attribut [JsonConverter(typeof(System.Text.Json.Serialization.JsonStringEnumMemberConverter))].

J'espère que cette explication vous aidera ! Faites-moi savoir si vous avez d'autres questions.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn