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

ASP.NET Core 6 Web API中集合内多态类型序列化问题求助

ASP.NET Core 6 Web API 多态集合序列化解决方案

默认情况下,System.Text.Json仅会序列化对象的声明类型属性,导致你的Derived实例的b字段被忽略,同时Swagger也无法识别集合中的派生类型。以下是两种合规且优雅的解决思路:

1. 配置Json序列化以支持多态

你可以通过全局配置或特性标记,让序列化器识别并序列化派生类型的完整属性:

方式一:全局配置(Program.cs)

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.TypeInfoResolverChain.Insert(0, new DefaultJsonTypeInfoResolver
        {
            Modifiers =
            {
                typeInfo =>
                {
                    if (typeInfo.Type == typeof(Base))
                    {
                        typeInfo.PolymorphismOptions = new JsonPolymorphismOptions
                        {
                            // 添加所有派生类型映射
                            DerivedTypes = { new JsonDerivedType(typeof(Derived), nameof(Derived)) },
                            // 可选:自定义类型鉴别器的键名,默认是"$type"
                            TypeDiscriminatorPropertyName = "$type"
                        };
                    }
                }
            }
        });
    });

配置后,接口返回的JSON会包含派生类型标识和完整属性:

{
  "data": [
    {
      "$type": "Derived",
      "b": 10,
      "a": 20
    }
  ]
}

方式二:特性标记基类

直接在基类上添加[JsonDerivedType]特性,更简洁直观:

[JsonDerivedType(typeof(Derived), nameof(Derived))]
public abstract record Base(int a);
public record Derived(int b, int a): Base(a);

这种方式无需额外全局配置,序列化器会自动识别派生类型。

2. 修复Swagger类型注解

默认Swagger无法自动识别多态集合中的派生类型,需手动配置SwaggerGen:

builder.Services.AddSwaggerGen(options =>
{
    // 为Base类型配置多态Schema
    options.MapType<Base>(() => new OpenApiSchema
    {
        Type = "object",
        OneOf = new List<OpenApiSchema>
        {
            options.SchemaGenerator.GenerateSchema(typeof(Derived), options.SchemaRepository)
        },
        // 补充类型鉴别器的文档描述
        Properties = new Dictionary<string, OpenApiSchema>
        {
            ["$type"] = new OpenApiSchema { Type = "string", Description = "类型标识" }
        },
        Required = new HashSet<string> { "$type" }
    });
});

配置后,Swagger文档会正确展示Base类型可接受的派生类型及所有属性,无需使用object[]或欺骗性注解。

内容的提问来源于stack exchange,提问作者Seva Alekseyev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 09:30:37