Home > Backend Development > C++ > How to Specify Custom Names for Enum Values in System.Text.Json?

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

DDD
Release: 2025-01-14 10:37:43
Original
320 people have browsed it

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

System.Text.Json: How do I specify a custom name for an enum value?

This capability is not available out of the box in .NET Core 3.0, .NET 5, .NET 6.0, .NET 7.0, or .NET 8.0. Therefore, you will need to create your own JsonConverterFactory that serializes enums with custom value names specified by attributes, or use a NuGet package that does the same, such as Macross.Json.Extensions.

If you are working in .NET 7 or later, or only need to serialize but not deserialize enums with custom names in earlier versions, custom names can be easily supported by creating a JsonConverterFactory that adapts JsonStringEnumConverter by constructing a customized JsonNamingPolicy for each enum with [EnumMember(Value = "xxx")] applied to any enum value.

Here are the steps involved:

  1. Create a custom converter:
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);
}
Copy after login
  1. Decorate your enum:
public enum Example
{
    Trick,
    Treat,
    [EnumMember(Value = "Trick-Or-Treat")]
    TrickOrTreat,
}
Copy after login
  1. Use the converter standalone:
var options = new JsonSerializerOptions
{
    Converters = { new JsonEnumMemberStringEnumConverter() },
    // Set other options as required:
    WriteIndented = true,
};
var json = JsonSerializer.Serialize(values, options);
Copy after login
  1. Register the converter with ASP.NET Core:

Refer to the answer to this question by Mani Gandham for guidance on how to do this.

Notes:

  • In .NET 6 and earlier, JsonStringEnumConverter ignores its naming policy during deserialization; this issue was fixed in pull request 73348.
  • In .Net Core 3.x, the converter may not work as desired with [Flags] enums. This issue was fixed in Issue #31622 in .NET 5.
  • If you need to round-trip an enum with custom value names in .NET 6 or earlier, you will need to create a generic converter converter factory from scratch.
  • An alternative solution is to use JsonStringEnumMemberConverter from the Macross.Json.Extensions package. Install the package and then decorate your enum with the attribute [JsonConverter(typeof(System.Text.Json.Serialization.JsonStringEnumMemberConverter))].

I hope this explanation helps! Let me know if you have any other questions.

The above is the detailed content of How to Specify Custom Names for Enum Values in System.Text.Json?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template