System.Text.Json: 列挙値のカスタム名を指定するにはどうすればよいですか?
この機能は、 .NET Core 3.0、.NET 5、.NET 6.0、.NET 7.0、または .NET のボックス8.0。したがって、属性で指定されたカスタム値名で列挙型をシリアル化する独自の JsonConverterFactory を作成するか、同じことを行う Macross.Json.Extensions などの NuGet パッケージを使用する必要があります。 .NET 7 以降、または以前のバージョンではカスタム名の列挙型をシリアル化するだけで逆シリアル化は必要ない場合、カスタム名は、 [EnumMember(Value = "xxx")] を任意の列挙値に適用して、列挙ごとにカスタマイズされた JsonNamingPolicy を構築することで、JsonStringEnumConverter を適応させる JsonConverterFactory。
関連する手順は次のとおりです。
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);
.NET 6 以前では、JsonStringEnumConverter は逆シリアル化中にその名前付けポリシーを無視します。この問題はプル リクエスト 73348 で修正されました。
以上がSystem.Text.Json で列挙値のカスタム名を指定する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。