使用.NET Core中的System.Text.Json序列化器功能,如何为枚举值指定自定义值,类似于JsonPropertyName
?例如:
public enum Example {
Trick,
Treat,
[JsonPropertyName("Trick-Or-Treat")] // Error: Attribute 'JsonPropertyName' is not valid on this declaration type. It is only valid on 'property, indexer' declarations.
TrickOrTreat
}
3条答案
按热度按时间y53ybaqx1#
目前.net-core-3.0、.net-5、.net-6.0或.net-7.0中不支持开箱即用。当前有一个问题 * Support for EnumMemberAttribute in JsonConverterEnum #31081 *[1]请求此功能。在此期间,您将需要创建自己的
JsonConverterFactory
,该JsonConverterFactory
使用由属性指定的自定义值名称序列化枚举。如果您需要 * 往返 * 一个具有自定义值名称的枚举,您将需要从头开始创建一个通用转换器+转换器工厂。这在一般情况下有点涉及,因为需要处理整数和字符串值的解析,重命名
[Flags]
枚举值的每个组件,以及所有可能的底层类型(byte
,short
,int
,long
,ulong
等)的枚举。Macross.Json.Extensions
中的JsonStringEnumMemberConverter
在enum用[EnumMember(Value = "custom name")]
属性修饰时似乎提供了此功能;安装软件包Macross.Json.Extensions
,然后执行以下操作:请参阅此处的文档以了解使用细节。
或者你可以自己卷。下面示出了一种可能性。它是针对.NET 6编写的,需要一些向后移植到早期版本:
如果您的
enum
使用EnumMember
属性进行注解,请使用JsonEnumMemberStringEnumConverter
。如果像问题中那样使用JsonPropertyName
属性进行注解,请使用JsonPropertyNameStringEnumConverter
。备注:
JsonStringEnumConverter
,它在阅读时不完全支持命名策略)。JsonStringEnumConverter
一致。演示小提琴here。
如果您只需要 * 序列化 * 一个具有自定义值名称的枚举,这可以通过创建一个
JsonConverterFactory
来更容易地完成,该JsonConverterFactory
通过为每个enum
类型构造一个自定义的JsonNamingPolicy
来适应JsonStringEnumConverter
,该JsonConverterFactory
类型将查找枚举成员上是否存在[EnumMember(Value = "xxx")]
属性,如果找到任何属性,则将成员名称Map到属性的值。(我选择EnumMember
是因为这是Newtonsoft支持的属性。首先,介绍以下转换器:
然后装饰你的
enum
:并按如下方式独立使用转换器:
要向www.example.com核心注册转换器asp.net,请参见例如this answer到 * JsonConverter equivalent in using System.Text.Json *,通过Mani Gandham。
备注:
JsonConverterFactory
在反序列化过程中忽略了它的命名策略;详情请参见 * System.Text.Json: JsonStringEnumConverter ignores its JsonNamingPolicy during deserialization. #31619 *。[Flags]
枚举的要求工作,例如:像
Example.TrickOrTreat
这样的简单值可以正确重命名,但是像Example.Trick | Example.TrickOrTreat
这样的复合值则不能。后者的结果应该是"Trick, Trick-Or-Treat"
,但实际上是"Trick, TrickOrTreat"
。问题的原因是每个特定枚举类型
T
的基础JsonConverterEnum<T>
使用构造的复合名称调用ConvertName
一次,而不是使用复合名称的每个组件多次。如果需要解决方法,在DictionaryLookupNamingPolicy.ConvertName()
中,可以尝试将传入的名称拆分为逗号分隔的组件,重新Map每个组件,然后重新组合结果。为了比较,Json.NET的
StringEnumConverter
在复合标志值的每个组件上调用等效的方法NamingStrategy.ResolvePropertyName(string name)
,这似乎更正确。在.Net 5中,这是固定的,请参阅Issue #31622了解详细信息。
演示小提琴here。
[1]关闭支持System.Text.Json support to System.Runtime.Serialization #29975。
643ylb082#
对于.NET5.0或更高版本,可以添加JsonConverter
序列化模型
使用和测试
此转换器仅可用于序列化
6ljaweal3#
在.net-core-5.0和asp.net-core-5.0中,Microsoft通过JsonStringEnumConverter Class添加了对反序列化/序列化枚举的支持。
像这样装饰枚举的值:
给定一个像这样的类:
您可以使用JsonStringEnumConverter内联序列化类的示例,如下所示:
如果你使用的是ASP.NET Core 5,那么你可以在启动时配置应用程序,使用JsonStringEnumConverter来序列化所有传入的请求:
更多阅读:How to serialize and deserialize (marshal and unmarshal) JSON in .NET Core。如果你正在使用ASP.NET,那么这也是你感兴趣的:JsonSerializerOptions的Web默认值。