含多态属性的Response类无法暴露派生类,如何解决?
解决Swagger无法显示接口派生类的问题
当Swagger生成JSON时仅展示接口类型(如IResponseDetails),却不显示其派生类(如SomethingDetails),可以通过以下几种方式解决:
方法一:使用[KnownType]特性
在接口或包含接口属性的类上添加[KnownType]特性,明确告知序列化器和Swagger哪些类是该接口的实现类。
标注在接口上
[KnownType(typeof(SomethingDetails))] // 若有多个派生类,添加多个[KnownType]特性 [KnownType(typeof(AnotherDetails))] public interface IResponseDetails { }
标注在包含接口属性的类上
[KnownType(typeof(SomethingDetails))] public class APIResponse { public string Something { get; set; } public IResponseDetails ResponseDetails { get; set; } }
方法二:自定义Swagger Schema过滤器
创建Schema过滤器,手动让Swagger识别接口的派生类,适合需要灵活控制的场景。
- 实现
ISchemaFilter接口:
public class InterfaceSchemaFilter : ISchemaFilter { public void Apply(OpenApiSchema schema, SchemaFilterContext context) { // 仅处理IResponseDetails接口 if (context.Type != typeof(IResponseDetails)) return; // 生成所有派生类的Schema并添加到OneOf中 var implementations = new[] { typeof(SomethingDetails), typeof(AnotherDetails) }; schema.OneOf = implementations.Select(type => context.SchemaGenerator.GenerateSchema(type, context.SchemaRepository)).ToList(); // 可选:添加鉴别器字段,帮助Swagger区分不同类型 schema.Discriminator = new OpenApiDiscriminator { PropertyName = "$type", Mapping = implementations.ToDictionary( type => type.Name, type => new OpenApiReference { Type = ReferenceType.Schema, Id = type.Name }) }; } }
- 在Swagger配置中注册过滤器:
services.AddSwaggerGen(c => { c.SchemaFilter<InterfaceSchemaFilter>(); // 其他Swagger配置... });
方法三:配置JSON序列化器(适用于System.Text.Json)
若使用System.Text.Json作为序列化器,可在配置中指定接口的派生类,同时影响JSON序列化和Swagger Schema生成:
services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver { Modifiers = { typeInfo => { if (typeInfo.Type == typeof(IResponseDetails)) { typeInfo.PolymorphismOptions = new JsonPolymorphismOptions { TypeDiscriminatorPropertyName = "$type", IgnoreUnrecognizedTypeDiscriminators = true, DerivedTypes = { new JsonDerivedType(typeof(SomethingDetails), nameof(SomethingDetails)), new JsonDerivedType(typeof(AnotherDetails), nameof(AnotherDetails)) } }; } } } }; });
内容的提问来源于stack exchange,提问作者SeReGa
相关产品推荐
相关产品推荐

