使用 Blanket 策略将枚举序列化为具有蛇形大小写的字符串

问题描述 投票:0回答:1

我正在将一些库移至.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?

enums system.text.json .net-8.0
1个回答
0
投票

这在 .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 { }

然而,这需要提前了解所有枚举类型。没有办法制定一揽子政策。

© www.soinside.com 2019 - 2024. All rights reserved.