System.Text.Json反序列化自定义结构体属性转换失败问题
问题根因
System.Text.Json 内置的类型转换逻辑 不会自动调用C#自定义的隐式/显式类型转换运算符,这是它和Newtonsoft.Json的核心行为差异之一。
当前代码里的Side自定义结构体仅实现了Side -> string方向的隐式转换,既没有实现反向string -> Side的转换逻辑,也没有向STJ提供专属的类型转换规则,反序列化遇到JSON中"S": "BUY"的字符串值时,STJ找不到从string到Side的内置转换路径,直接抛出JsonException。
修复方案
给Side类型实现专属的JsonConverter<Side>,明确告诉STJ怎么完成字符串和Side实例的双向转换,步骤如下:
- 第一步:编写自定义转换器
using System.Text.Json; using System.Text.Json.Serialization; public class SideJsonConverter : JsonConverter<Side> { public override Side Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.String) throw new JsonException($"Side字段期望字符串类型值,实际收到{reader.TokenType}类型"); string? value = reader.GetString(); return value switch { "BUY" => Side.Buy, "SELL" => Side.Sell, _ => throw new JsonException($"不支持的Side值:{value}") }; } public override void Write(Utf8JsonWriter writer, Side value, JsonSerializerOptions options) { writer.WriteStringValue(value.Value); } }
- 第二步:注册转换器,二选一即可:
- 方式一:给
Side结构体加特性,全局所有用到Side类型的序列化/反序列化场景自动生效
[JsonConverter(typeof(SideJsonConverter))] public readonly struct Side { // 原有代码保持不变,可按需补充string到Side的隐式转换方便业务代码使用 public static implicit operator Side(string value) { return value switch { "BUY" => Buy, "SELL" => Sell, _ => throw new ArgumentOutOfRangeException(nameof(value), $"未知交易方向值:{value}") }; } // 其余原有结构体代码保持不变 private Side(string value) { Value = value; } public static Side Buy => new("BUY"); public static Side Sell => new("SELL"); public string Value { get; } public static implicit operator string(Side enm) { return enm.Value; } public override string ToString() { return Value; } }- 方式二:仅给
BinanceStreamOrderUpdate的Side属性加特性,只对该属性的反序列化生效
[JsonPropertyName("S")] [JsonConverter(typeof(SideJsonConverter))] public Side Side { get; init; } - 方式一:给
额外注意
你代码中其他和
Side类似的自定义结构体类型(比如SpotOrderType、TimeInForce、ExecutionType等),如果也是类似的字符串映射自定义值类型实现,都需要按同样方式编写专属JsonConverter,否则会触发同类转换异常。
如果这些类型是C#原生枚举类型,STJ默认会按数值做序列化/反序列化,要匹配接口返回的字符串值,给枚举类型加[JsonStringEnumConverter]特性即可。
内容的提问来源于stack exchange,提问作者nop
相关产品推荐
相关产品推荐

