using System.Collections;
using System.Collections.Generic;
using System.Text.Json.Serialization;
public class CustomEnumConverter : JsonConverterFactory
public override bool CanConvert(Type typeToConvert) => typeToConvert.IsEnum;
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) =>
(JsonConverter)Activator.CreateInstance(typeof(CustomConverter<>).MakeGenericType(typeToConvert))!;
class CustomConverter<T> : JsonConverter<T> where T : struct, Enum
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
reader.GetString()!.GetEnumValue<T>()!;
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) =>
writer.WriteStringValue(value.GetDescription<T>());
public static class EnumExtensions
const string prefix = "descriptions_";
public static string GetDescription<TEnum>(this TEnum value) where TEnum : struct, Enum => prefix + value.ToString();
public static TEnum GetEnumValue<TEnum>(this string value) where TEnum : struct, Enum => Enum.Parse<TEnum>(value.StartsWith(prefix) ? value.AsSpan().Slice(prefix.Length) : value.AsSpan(), true);
[JsonConverter(typeof(CustomEnumConverter))]
public SomeEnum? SomeEnum { get; set; }
public Enum2 Enum2 { get; set; }
public static void Test()
var model = new Model { SomeEnum = SomeEnum.Bar, Enum2 = Enum2.Bar2 };
var options = new JsonSerializerOptions
Converters = { new CustomEnumConverter() },
var json = JsonSerializer.Serialize(model, options);
var model2 = JsonSerializer.Deserialize<Model>(json, options);
Assert.AreEqual(model.SomeEnum, model2?.SomeEnum);
Assert.AreEqual(model.Enum2, model2?.Enum2);
public static void Main()
Console.WriteLine("Environment version: {0} ({1}), {2}", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , Environment.Version, Environment.OSVersion);
Console.WriteLine("System.Text.Json version: " + typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");