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

ASP.NET Core Web API如何反序列化Swagger的oneOf类型请求体?

解决ASP.NET Core 6最小API多态JSON反序列化问题

1. 配置System.Text.Json的多态支持

默认的System.Text.Json不自动处理多态类型转换,需要通过配置类型映射和鉴别字段,让反序列化器识别子类。

示例代码

先定义你的形状类:

public abstract class Shape
{
    // 自定义类型鉴别字段,用于标识具体子类
    public string Type { get; set; }
}

public class Circle : Shape
{
    public double Radius { get; set; }
}

public class Square : Shape
{
    public double SideLength { get; set; }
}

在Program.cs中配置Json序列化选项,添加多态类型信息:

builder.Services.Configure<JsonOptions>(options =>
{
    options.SerializerOptions.TypeInfoResolverChain.Insert(0, CreateShapePolymorphicTypeInfo());
});

// 构建多态类型映射规则
private static JsonTypeInfo CreateShapePolymorphicTypeInfo()
{
    var context = new JsonSerializerContext(new JsonSerializerOptions());
    var shapeTypeInfo = context.GetTypeInfo(typeof(Shape)) as JsonDerivedTypeInfo;
    
    // 绑定子类与鉴别字段值
    shapeTypeInfo.DerivedTypes.Add(new JsonDerivedType(typeof(Circle), "Circle"));
    shapeTypeInfo.DerivedTypes.Add(new JsonDerivedType(typeof(Square), "Square"));
    
    return shapeTypeInfo;
}

2. 同步Swagger配置以匹配鉴别规则

为了让Swagger文档正确提示客户端传入类型鉴别字段,需要调整Swashbuckle配置:

builder.Services.AddSwaggerGen(c =>
{
    c.UseOneOfForPolymorphism();
    // 指定基类对应的子类集合
    c.SelectSubTypesUsing(baseType =>
    {
        if (baseType == typeof(Shape))
        {
            return new[] { typeof(Circle), typeof(Square) };
        }
        return Enumerable.Empty<Type>();
    });
    // 添加鉴别字段到Swagger Schema
    c.SchemaFilter<PolymorphismSchemaFilter>();
});

// 自定义SchemaFilter,完善Swagger文档中的类型鉴别字段定义
public class PolymorphismSchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (context.Type == typeof(Shape))
        {
            schema.Properties["Type"] = new OpenApiSchema
            {
                Type = "string",
                Enum = new List<IOpenApiAny>
                {
                    new OpenApiString("Circle"),
                    new OpenApiString("Square")
                }
            };
            schema.Required.Add("Type");
        }
    }
}

3. 适配复杂对象的部分字段场景

如果是复杂对象中的某个字段为多态类型(比如public class User { public Shape FavoriteShape { get; set; } }),上述全局配置依然生效。只要JSON中对应字段包含正确的类型鉴别值,反序列化器就能自动将其转换为对应的子类。

关键注意事项

  • 确保子类有符合要求的构造函数(无参、单参数或标记JsonConstructorAttribute的参数化构造函数),避免出现你遇到的构造函数异常
  • 类型鉴别字段的名称和值,要在Json配置与Swagger配置中完全一致
  • 若使用默认的$type字段,客户端需传入包含类型全名的字符串(如"$type": "YourNamespace.Circle, YourAssembly"),自定义字段对客户端更友好

配置完成后,客户端传入如下JSON即可正确反序列化为Circle子类:

{
  "Type": "Circle",
  "Radius": 5.0
}

内容的提问来源于stack exchange,提问作者Overlord Zurg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 16:24:56