我正在使用一个 API 处理以 JSON 格式提交大量数据(例如 10MB+)的请求。迄今为止,我们一直在使用
Newtonsoft.Json
,但最近我们遇到了性能问题,主要与将请求数据反序列化为适当类型所需的时间和/或内存量有关,因此我们一直在考虑切换到System.Text.Json
,根据我们的内部基准测试,这两个指标都明显更好。
我在修改现有代码时遇到问题的地方是我们有一些围绕处理枚举编写的自定义反序列化逻辑,采用 JSON.NET 自定义转换器的形式。由于历史原因,我们有一些 API 客户使用一组与 API 期望值不同的枚举值!所以,我们的枚举可能看起来像这样:
public enum Allowances
{
[AlternativeValue("CD")] Car = 0,
[AlternativeValue("AD")] Transport = 1,
[AlternativeValue("LD")] Laundry = 2
}
public class AllowanceRequest
{
public Allowances Type { get; set; }
public decimal Value { get; set; }
}
所以客户 A 将提交他们的数据:
{ "type": "Car", "value": 25.75 }
客户 B 将提交他们的数据:
{ "type": 0, "value": 25.75 }
客户 C 将提交他们的数据:
{ "type": "CD", "value": 25.75 }
(我在这里给出了一个例子,但是有很多枚举使用了这个自定义属性,所以拥有一个特定于枚举的转换器并不是真正有效的方法——转换器需要相当通用)。
我很难理解
System.Text.Json
是如何处理枚举的自定义转换的,因为这似乎是一种特殊情况并且处理方式与常规类不同,需要使用 JsonConverterFactory
而不是 JsonConverter<>
的实现。当我尝试测试序列化代码时(参见 https://gist.github.com/davidkeaveny/ffa24630a953e46d02c4403a66c928a7),然后出现以下错误:
System.InvalidOperationException
The converter 'AlternativeValueJsonStringEnumConverter+CustomStringEnumConverter' is not compatible with the type 'System.Nullable`1[TestEnum]'.
at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_SerializationConverterNotCompatible(Type converterType, Type type)
at System.Text.Json.JsonSerializerOptions.GetConverterInternal(Type typeToConvert)
at System.Text.Json.JsonSerializerOptions.DetermineConverter(Type parentClassType, Type runtimePropertyType, MemberInfo memberInfo)
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.GetConverter(Type type, Type parentClassType, MemberInfo memberInfo, Type& runtimeType, JsonSerializerOptions options)
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.AddProperty(MemberInfo memberInfo, Type memberType, Type parentClassType, Boolean isVirtual, Nullable`1 parentTypeNumberHandling, JsonSerializerOptions options)
有没有人有编写自己的自定义枚举序列化代码的经验?