无法修改NuGet中API控制器,如何用SwashBuckle过滤器添加响应示例?
解决方案:通过IDocumentFilter为外部控制器添加响应Schema
问题分析
你之前的代码核心问题有两个:
- 直接使用
OpenApiString设置示例,导致Swagger/ReDoc将响应类型识别为字符串,而非MyClass的Schema结构。 - 未确保
MyClass的Schema已被SwashBuckle正确生成并添加到文档的组件定义中,可能导致引用失效。
正确实现代码
以下是等效于[ProducesResponseType(typeof(MyClass), (int)HttpStatusCode.Accepted)]的IDocumentFilter实现:
public class AddAcceptedResponseFilter : IDocumentFilter { public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) { // 替换为你的目标API路径(如"/api/Orders/Create") const string targetApiPath = "/api/YourController/YourAction"; if (!swaggerDoc.Paths.TryGetValue(targetApiPath, out var pathItem)) return; // 替换为目标HTTP方法(如OperationType.Post、OperationType.Get) if (!pathItem.Operations.TryGetValue(OperationType.Post, out var targetOperation)) return; const string acceptedStatusCode = "202"; // 如果202响应不存在,先创建基础响应对象 if (!targetOperation.Responses.ContainsKey(acceptedStatusCode)) { targetOperation.Responses[acceptedStatusCode] = new OpenApiResponse { Description = "请求已接受,正在处理中" }; } var acceptedResponse = targetOperation.Responses[acceptedStatusCode]; var jsonMediaType = MediaTypeNames.Application.Json; var myClassType = typeof(MyClass); // 获取MyClass的Schema标识(自动处理命名空间,避免同名类冲突) var schemaId = context.SchemaGenerator.GetSchemaId(myClassType); // 确保Schema已生成并添加到文档组件中 if (!swaggerDoc.Components.Schemas.ContainsKey(schemaId)) { var myClassSchema = context.SchemaGenerator.GenerateSchema(myClassType, context.SchemaRepository); swaggerDoc.Components.Schemas[schemaId] = myClassSchema; } // 绑定响应Content到MyClass的Schema acceptedResponse.Content[jsonMediaType] = new OpenApiMediaType { Schema = new OpenApiSchema { Reference = new OpenApiReference { Id = schemaId, Type = ReferenceType.Schema } } }; // 可选:自定义示例(使用OpenApiObject匹配Schema结构,而非字符串) var myClassSchema = swaggerDoc.Components.Schemas[schemaId]; myClassSchema.Example = new OpenApiObject { ["someProp"] = new OpenApiString("someVal"), ["anotherNumericProp"] = new OpenApiInteger(123), ["isActive"] = new OpenApiBoolean(true) }; } }
关键细节说明
- Schema ID 生成:使用
context.SchemaGenerator.GetSchemaId而非手动拼接类型名,避免因命名空间不同导致的同名类冲突。 - Schema 预生成:提前生成并注册
MyClass的Schema,确保Swagger和ReDoc能正确识别类型定义。 - 示例格式正确:使用
OpenApiObject(而非OpenApiString)定义示例,保证示例结构与Schema完全匹配,解决ReDoc的格式错误问题。
注册过滤器
在Swagger服务配置中添加该过滤器:
builder.Services.AddSwaggerGen(options => { options.DocumentFilter<AddAcceptedResponseFilter>(); });
内容的提问来源于stack exchange,提问作者Lazaro
相关产品推荐
相关产品推荐

