You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 00:25:29