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

ASP.NET Core多态反序列化缺失类型鉴别器时如何获取有效错误信息?

解决多态反序列化缺失类型鉴别器的友好错误问题

可以通过自定义JsonConverter<NotificationWeb>拦截缺失type字段的场景,统一返回和无效类型鉴别器一致的友好错误信息,具体实现如下:

1. 编写自定义转换器

public class NotificationWebConverter : JsonConverter<NotificationWeb>
{
    private readonly JsonConverter<NotificationWeb> _defaultConverter;

    public NotificationWebConverter(JsonSerializerOptions options)
    {
        // 获取框架默认的多态反序列化转换器
        _defaultConverter = (JsonConverter<NotificationWeb>)options.GetConverter(typeof(NotificationWeb));
    }

    public override NotificationWeb? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // 复制读取器,检查当前对象是否包含"type"字段
        var readerCopy = reader;
        if (readerCopy.TokenType != JsonTokenType.StartObject)
        {
            throw new JsonException("无效的通知对象格式");
        }

        bool hasTypeField = false;
        while (readerCopy.Read())
        {
            if (readerCopy.TokenType == JsonTokenType.PropertyName && readerCopy.GetString() == "type")
            {
                hasTypeField = true;
                break;
            }
            // 跳过属性值,继续遍历下一个属性
            if (readerCopy.TokenType == JsonTokenType.PropertyName)
            {
                readerCopy.Read();
                JsonSerializer.Skip(ref readerCopy);
            }
        }

        // 缺失type字段时抛出统一错误
        if (!hasTypeField)
        {
            throw new JsonException("类型鉴别器无效");
        }

        // 交给默认转换器处理正常的多态反序列化
        return _defaultConverter.Read(ref reader, typeToConvert, options);
    }

    public override void Write(Utf8JsonWriter writer, NotificationWeb value, JsonSerializerOptions options)
    {
        _defaultConverter.Write(writer, value, options);
    }
}

2. 注册转换器

有两种方式可以将自定义转换器接入系统:

方式一:通过特性绑定到抽象类

直接在NotificationWeb上添加JsonConverter特性:

[JsonConverter(typeof(NotificationWebConverter))]
[JsonPolymorphic(TypeDiscriminatorPropertyName = "type")]
[JsonDerivedType(typeof(EmailNotificationWeb), "Email")]
[JsonDerivedType(typeof(SmsNotificationWeb), "Sms")]
public abstract record NotificationWeb;

方式二:全局配置(适用于ASP.NET Core)

在项目启动配置中添加转换器到序列化选项:

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.Converters.Add(new NotificationWebConverter(options.JsonSerializerOptions));
    });

3. 效果说明

  • 当请求数组元素缺失type字段时,会抛出包含“类型鉴别器无效”的异常,和传入无效type值时的错误提示保持一致;
  • 正常传入有效type字段时,依然保留原有多态反序列化逻辑;
  • 传入无效type值时,框架默认的“未知类型”错误会继续生效,若需要完全统一错误信息,可在转换器中额外处理未知类型的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 21:38:32