.NET 6中如何用System.Text.Json处理字符串化数值枚举
解决System.Text.Json解析字符串形式枚举数值的问题
System.Text.Json默认仅支持两种枚举解析方式:纯数值(如1)或枚举名称字符串(如"InnerJoin"),不兼容前端传来的字符串包裹的数值(如"1"),这也是迁移时遇到的核心问题。以下是可直接复用的自定义转换器实现,完美兼容三种输入格式:
自定义枚举转换器代码
public class StringNumberEnumConverter<TEnum> : JsonConverter<TEnum> where TEnum : struct, Enum { public override TEnum Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // 处理字符串类型输入 if (reader.TokenType == JsonTokenType.String) { var stringValue = reader.GetString(); // 优先尝试转数值解析 if (int.TryParse(stringValue, out var intValue)) { return (TEnum)Enum.ToObject(typeToConvert, intValue); } // 数值解析失败,按枚举名称解析(忽略大小写) if (Enum.TryParse(stringValue, true, out TEnum enumValue)) { return enumValue; } // 解析失败抛出异常,也可按需返回默认值(如Undefined) throw new JsonException($"无法将值 '{stringValue}' 转换为枚举 {typeToConvert.Name}"); } // 处理纯数值类型输入 else if (reader.TokenType == JsonTokenType.Number) { return (TEnum)Enum.ToObject(typeToConvert, reader.GetInt32()); } // 其他不支持的令牌类型抛出异常 throw new JsonException($"不支持的令牌类型 {reader.TokenType} 用于枚举解析"); } public override void Write(Utf8JsonWriter writer, TEnum value, JsonSerializerOptions options) { // 序列化时输出数值,如需输出枚举名称可改为 writer.WriteStringValue(value.ToString()) writer.WriteNumberValue(Convert.ToInt32(value)); } }
使用方式
1. 单个属性配置
直接在目标枚举属性上添加特性标记:
public class ExampleClass { [JsonConverter(typeof(StringNumberEnumConverter<OperationType>))] public OperationType Operation { get; set; } }
2. 全局配置(所有枚举生效)
若需让整个应用的枚举都支持该解析逻辑,可在JsonSerializerOptions中注册转换器:
var jsonOptions = new JsonSerializerOptions(); jsonOptions.Converters.Add(new StringNumberEnumConverter<OperationType>()); // 解析示例 var jsonString = "{\"operation\": \"1\"}"; var result = JsonSerializer.Deserialize<ExampleClass>(jsonString, jsonOptions);
效果验证
现在三种输入格式均能正常解析:
- 字符串数值:
{"operation": "1"}→ 解析为OperationType.InnerJoin - 纯数值:
{"operation": 1}→ 解析为OperationType.InnerJoin - 枚举名称:
{"operation": "InnerJoin"}→ 解析为OperationType.InnerJoin
内容的提问来源于stack exchange,提问作者Russ
相关产品推荐
相关产品推荐

