ASP.NET Core Swashbuckle 基类集合包装类无法返回子类属性如何解决
解决方案
这个问题的核心是两层配置缺失:一是System.Text.Json默认不启用多态序列化,只会序列化声明类型(也就是Base)的属性;二是Swashbuckle默认不会自动为集合中的基类元素应用多态Schema配置。按以下步骤调整即可:
1. 先修复示例代码的基础错误
- 你的
Sub1类没有显式继承Base,首先修正继承关系:
// 错误写法:public class Sub1 // 正确写法: public class Sub1 : Base { public string? Name { get; set; } }
Base类的Type属性需要加public访问修饰符,否则序列化和Swagger鉴别器都会识别失败:
public abstract class Base { public MyObjType Type { get;set;} }
2. 配置System.Text.Json多态序列化
你可以选两种方式任意一种:
- 方式一:直接给基类加序列化特性,代码侵入性低:
using System.Text.Json.Serialization; [JsonPolymorphic(TypeDiscriminatorPropertyName = "type")] [JsonDerivedType(typeof(Sub1), typeDiscriminator: nameof(MyObjType.T1))] [SwaggerDiscriminator("type")] [SwaggerSubType(typeof(Sub1), DiscriminatorValue = nameof(MyObjType.T1))] public abstract class Base { public MyObjType Type { get;set;} }
- 方式二:全局配置多态转换器,适合基类子类较多的场景,在
AddJsonOptions中添加对应配置即可。
3. 添加Swagger多态集合Schema过滤器
Swashbuckle默认不会递归识别集合元素的多态配置,需要自定义Schema过滤器来补全:
- 先定义过滤器类:
using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; public class PolymorphicCollectionSchemaFilter : ISchemaFilter { public void Apply(OpenApiSchema schema, SchemaFilterContext context) { // 匹配集合包装类 if (context.Type == typeof(BaseCollection)) { var itemsSchema = schema.Properties["items"]; // 把所有Base的子类Schema加到anyOf配置里 itemsSchema.AnyOf = new List<OpenApiSchema> { context.SchemaGenerator.GenerateSchema(typeof(Sub1), context.SchemaRepository) // 后续新增其他Base子类,在这里加对应行即可 }; // 清除原有基类引用避免冲突 itemsSchema.Reference = null; } } }
- 在
AddSwaggerGen中注册过滤器:
services.AddSwaggerGen(c => { c.EnableAnnotations(enableAnnotationsForInheritance: true, enableAnnotationsForPolymorphism: true); // 新增这一行 c.SchemaFilter<PolymorphicCollectionSchemaFilter>(); });
调整完成后重新启动项目,BaseCollection的Items字段就会正确显示所有子类的属性,序列化返回结果也会带上子类字段。
内容的提问来源于stack exchange,提问作者Michael Sabin
相关产品推荐
相关产品推荐

