如何在OperationFilter中获取API的响应内容类型?
从.NET API元数据获取响应内容类型(自定义OperationFilter实现)
我们有一个配置了application/json和application/xml两种响应格式的.NET API,代码如下:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers().AddXmlSerializerFormatters(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(options => options.OperationFilter<CustomFilter>()); var app = builder.Build(); app.UseSwagger(); app.UseSwaggerUI(); app.MapControllers(); app.Run(); [ApiController] public class FooController : ControllerBase { [HttpGet("/")] public void Get() { } }
这个API支持返回上述两种格式的响应,现在需要实现一个自定义OperationFilter来生成包含这些响应类型的OpenAPI文档,但当前代码里的响应类型是硬编码的,需要改为从API元数据中动态获取。现有CustomFilter代码如下:
public class Foo { } public class CustomFilter : IOperationFilter { public void Apply(OpenApiOperation operation, OperationFilterContext context) { var schema = context.SchemaGenerator.GenerateSchema(typeof(Foo), context.SchemaRepository); operation.Responses.Clear(); var response = new OpenApiResponse(); var apiResponseTypes = new[] { "application/json", "application/xml" }; // <- 如何从API元数据获取? foreach(string responseType in apiResponseTypes) { response.Content.Add(responseType, new OpenApiMediaType { Schema = schema }); } operation.Responses.Add("200", response); } }
解决方案
可以通过OperationFilterContext提供的ApiDescription元数据来获取接口支持的响应内容类型,修改后的CustomFilter代码如下:
public class Foo { } public class CustomFilter : IOperationFilter { public void Apply(OpenApiOperation operation, OperationFilterContext context) { var schema = context.SchemaGenerator.GenerateSchema(typeof(Foo), context.SchemaRepository); operation.Responses.Clear(); var response = new OpenApiResponse(); // 从API元数据中提取所有支持的响应内容类型 var apiResponseTypes = context.ApiDescription.SupportedResponseTypes .SelectMany(responseType => responseType.ApiResponseFormats) .Select(format => format.MediaType) .Distinct(); foreach(string responseType in apiResponseTypes) { response.Content.Add(responseType, new OpenApiMediaType { Schema = schema }); } operation.Responses.Add("200", response); } }
代码说明
context.ApiDescription:包含当前接口的完整元数据信息SupportedResponseTypes:列出接口定义的所有响应类型配置ApiResponseFormats:每个响应类型对应的媒体格式集合,从中取出MediaType字段就是我们需要的内容类型字符串Distinct():用于去重,避免重复添加相同的内容类型
如果需要针对不同状态码配置响应格式,可以结合SupportedResponseTypes中的StatusCode属性进行匹配,实现更精细化的控制。
内容的提问来源于stack exchange,提问作者vernou
相关产品推荐
相关产品推荐

