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:
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 && 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); }
public enum Example { Trick, Treat, [EnumMember(Value = "Trick-Or-Treat")] TrickOrTreat, }
var options = new JsonSerializerOptions { Converters = { new JsonEnumMemberStringEnumConverter() }, // Set other options as required: WriteIndented = true, }; var json = JsonSerializer.Serialize(values, options);
Refer to the answer to this question by Mani Gandham for guidance on how to do this.
Notes:
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!