我正在将一些库移至.net 8,并尝试使用新的 JsonNamingPolicy.SnakeCaseLower 进行枚举(我目前使用一个自定义转换器,它使用反射,但我想放弃它)。 我可以使用这个 JsonSerializerOptions 将枚举序列化为蛇形案例
JsonSerializerOptions options = new()
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
};
options.Converters.Add(new JsonStringEnumConverter(namingPolicy: JsonNamingPolicy.SnakeCaseLower));
问题是,根据文档,AOT 不支持非泛型 JsonStringEnumConverter 类型。给出的解决方案是在继承于
[JsonSourceGenerationOptions(UseStringEnumConverter = true)]
的类中使用 JsonSerializerContext
但随后我失去了枚举的命名策略。
有没有一种方法可以以 AOT 友好的方式在全局范围内对所有枚举使用 JsonNamingPolicy.SnakeCaseLower?
这在 .NET 8 中尚未实现,请参阅 [API 提案]:添加选项以指定 JsonNamingPolicy 以在 JsonSourceGenerationOptions 上进行枚举序列化 #92828。
最近在
中添加了UseStringEnumConverter
标志,但无法为这些转换器配置命名策略。 -线。JsonSourceGenerationOptions
听起来很有道理。 -eiriktsarpalis.
MSFT 的 Eirik Tsarpalis 建议,作为一种解决方法,为所需的命名策略定义
JsonStringEnumConverter<TEnum>
子类型,并为每个枚举将其添加到序列化上下文中,例如像这样:
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 { }
然而,这需要提前了解所有枚举类型。没有办法制定一揽子政策。