It looks like JsonStringEnumConverter
requires dynamic code and we should switch to JsonStringEnumConverter<T>
in AOT.
[JsonConverter(typeof(JsonStringEnumConverter<MyEnum>))]
public enum MyEnum { Foo, Bar }
[JsonSerializable(typeof(MyEnum))]
public partial class MyJsonSerializerContext : JsonSerializerContext { }
I have many enums. Is it possible to create a global policy so that each enum is converted into its string representation and we avoid attributes?
As stated in How to use source generation in System.Text.Json: Blanket policy, you can apply [JsonSourceGenerationOptions(UseStringEnumConverter = true)]
to your serialization contexts to force all enums to be serialized as strings:
Instead of using the
JsonStringEnumConverter<TEnum>
type, you can apply a blanket policy to serialize enums as strings by using the JsonSourceGenerationOptionsAttribute. Create a JsonSerializerContext class and annotate it with the JsonSerializableAttribute and JsonSourceGenerationOptionsAttribute attributes
Thus you should modify your MyJsonSerializerContext
as follows:
[JsonSourceGenerationOptions(UseStringEnumConverter = true)]
[JsonSerializable(typeof(MyEnum))]
public partial class MyJsonSerializerContext : JsonSerializerContext { }
The code shown in the question does not use a naming policy such as JsonNamingPolicy.CamelCase
for enum serialization. If you need one, note that, as indicated in issue #92828, as of .NET 8 there does not seem to be a way to configure one with this approach. I.e. the setting UseStringEnumConverter = true
lacks feature parity with new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
. The workaround suggested by MSFT's Eirik Tsarpalis is to apply the required converters to the serialization context instead of to each enum:
public class CamelCaseEnumConverter<TEnum>() :
JsonStringEnumConverter<TEnum>(JsonNamingPolicy.CamelCase) where TEnum : struct, Enum;
[JsonSourceGenerationOptions(
Converters = new[] {
// Add all known enums here
typeof(CamelCaseEnumConverter<MyEnum>)}),
// Add all known enums here also (which you were already doing):
JsonSerializable(typeof(MyEnum))]
public partial class MyJsonSerializerContext : JsonSerializerContext { }
For more see: Use a Blanket policy to serialize enums as strings with snake case.