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

.Net Core 3中是否存在StringEnumConverter的替代方案?

在.NET Core 3+中扩展System.Text.Json的枚举字符串转换(无需重写完整转换器)

我完全懂你的困扰——之前用Newtonsoft.Json的时候,继承StringEnumConverter就能轻松给枚举字符串绑定加验证、自定义错误信息,结果到了.NET Core 3及以后,System.Text.Json的JsonStringEnumConverter直接被标成sealed了,想继承扩展门都没有,又不想退回到Newtonsoft,也不想从零写个完整的枚举转换器?别慌,这里有个巧妙的办法,不用重复造轮子,直接复用微软内置转换器的逻辑,同时加上你要的自定义验证。

核心思路:用JsonConverterFactory包装内置转换器

JsonConverterFactory是System.Text.Json里用来批量创建转换器的接口,我们可以用它来“包装”现有的JsonStringEnumConverter,在它的序列化/反序列化流程前后插入自定义逻辑——比如验证枚举值是否合法,或者抛出带自定义信息的异常。

实现代码示例

下面这个工厂类会帮你封装内置的枚举转换器,同时添加自定义验证:

public class ValidatingJsonStringEnumConverterFactory : JsonConverterFactory
{
    // 复用内置的JsonStringEnumConverter处理基础转换
    private readonly JsonStringEnumConverter _innerConverter;

    public ValidatingJsonStringEnumConverterFactory(JsonNamingPolicy namingPolicy = null, bool allowIntegerValues = true)
    {
        _innerConverter = new JsonStringEnumConverter(namingPolicy, allowIntegerValues);
    }

    // 只处理枚举类型,和内置转换器保持一致
    public override bool CanConvert(Type typeToConvert)
    {
        return _innerConverter.CanConvert(typeToConvert);
    }

    public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
    {
        // 获取内置转换器的实例
        var innerConverter = (JsonConverter)_innerConverter.CreateConverter(typeToConvert, options);
        // 返回包装后的转换器,插入自定义逻辑
        return new ValidatingEnumConverterWrapper(typeToConvert, innerConverter);
    }

    // 内部包装类,负责插入自定义逻辑
    private class ValidatingEnumConverterWrapper : JsonConverter
    {
        private readonly Type _enumType;
        private readonly JsonConverter _innerConverter;

        public ValidatingEnumConverterWrapper(Type enumType, JsonConverter innerConverter)
        {
            _enumType = enumType;
            _innerConverter = innerConverter;
        }

        public override bool CanConvert(Type typeToConvert)
        {
            return _innerConverter.CanConvert(typeToConvert);
        }

        public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            // 先让内置转换器完成字符串到枚举的基础转换
            var enumValue = _innerConverter.Read(ref reader, typeToConvert, options);
            
            // 这里添加你的自定义验证逻辑,比如检查枚举值是否被定义
            if (!Enum.IsDefined(_enumType, enumValue))
            {
                throw new JsonException($"无效的枚举值:{enumValue},请使用{_enumType.Name}枚举中定义的有效值");
            }

            return enumValue;
        }

        public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options)
        {
            // 序列化逻辑直接复用内置转换器,也可以在这里加自定义处理(比如格式化枚举值)
            _innerConverter.Write(writer, value, options);
        }
    }
}

如何使用

只需要把这个工厂添加到JsonSerializerOptions的转换器集合里就可以了,完全兼容内置转换器的所有配置(比如驼峰命名、允许整数值):

var jsonOptions = new JsonSerializerOptions
{
    // 添加我们的自定义工厂,同时指定命名策略
    Converters.Add(new ValidatingJsonStringEnumConverterFactory(JsonNamingPolicy.CamelCase))
};

// 测试反序列化:如果传入无效的枚举字符串,就会抛出我们自定义的错误信息
try
{
    var result = JsonSerializer.Deserialize<OrderStatus>("\"InvalidStatus\"", jsonOptions);
}
catch (JsonException ex)
{
    Console.WriteLine(ex.Message); // 输出:无效的枚举值:InvalidStatus,请使用OrderStatus枚举中定义的有效值
}

进阶玩法:针对特定枚举类型定制验证

如果需要给不同的枚举类型加不同的验证逻辑,只需要在CreateConverter方法里判断typeToConvert,返回不同的包装器即可。比如:

public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
    var innerConverter = (JsonConverter)_innerConverter.CreateConverter(typeToConvert, options);
    
    if (typeToConvert == typeof(OrderStatus))
    {
        return new OrderStatusValidatingWrapper(typeToConvert, innerConverter);
    }
    else if (typeToConvert == typeof(UserRole))
    {
        return new UserRoleValidatingWrapper(typeToConvert, innerConverter);
    }
    
    return new ValidatingEnumConverterWrapper(typeToConvert, innerConverter);
}

这样就能针对不同枚举类型实现差异化的验证逻辑,同时依然复用内置转换器的核心功能。


内容的提问来源于stack exchange,提问作者Ilya Chernomordik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 16:52:31