2

I'm moving some libraries to .NET 8 and I'm trying to use the new JsonNamingPolicy.SnakeCaseLower for enums (I have a custom converter that I currently use that uses reflection but I want to drop it). I can serialize an enum to snake case using this JsonSerializerOptions:

JsonSerializerOptions options = new()
{
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
    PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
};

options.Converters.Add(new JsonStringEnumConverter(namingPolicy: JsonNamingPolicy.SnakeCaseLower));

The problem is that according to the documentation The non-generic JsonStringEnumConverter type is not supported for AOT. The solution given is using [JsonSourceGenerationOptions(UseStringEnumConverter = true)] in the class inheriting from JsonSerializerContext but then I lose the naming policy for enums.

Is there a way to use JsonNamingPolicy.SnakeCaseLower globally for all enums in an AOT-friendly way?

0

1 Answer 1

2

This is not implemented as of .NET 8, see [API Proposal]: Add option to specify JsonNamingPolicy for enum serialization on JsonSourceGenerationOptions #92828.

Recently there has been added UseStringEnumConverter flag to JsonSourceGenerationOptions, but there is no way to configure naming policy for these converters. -ithline.

Sounds reasonable. -eiriktsarpalis.

MSFT's Eirik Tsarpalis suggests, as a workaround, to define a JsonStringEnumConverter<TEnum> subtype for your required naming policy and, for each enum, add it to your serialization context, e.g. like so:

public class SnakeCaseLowerStringEnumConverter<TEnum>() 
    : JsonStringEnumConverter<TEnum>(JsonNamingPolicy.SnakeCaseLower) 
    where TEnum : struct, Enum;

[JsonSourceGenerationOptions(
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
    PropertyNamingPolicy = JsonKnownNamingPolicy.SnakeCaseLower,
    Converters = new[] { 
        // Add all known enums here
        typeof(SnakeCaseLowerStringEnumConverter<FirstEnum>), 
        typeof(SnakeCaseLowerStringEnumConverter<SecondEnum>),
        //...
        typeof(SnakeCaseLowerStringEnumConverter<LastEnum>)})]
// Add all known enums here also
[JsonSerializable(typeof(FirstEnum)), 
 JsonSerializable(typeof(SecondEnum)),
 //...
 JsonSerializable(typeof(LastEnum))]
// And also add all other root types to be serialized in this context
[JsonSerializable(typeof(MyModel)),] 
public partial class SnakeCaseLowerContext : JsonSerializerContext { }

This, however, requires knowing all the enum types in advance. There's no way to set a blanket policy.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.