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

如何为同一200OK状态码配置多个响应类型并在Swagger UI正常展示

同一状态码多响应类型展示方案

原生[ProducesResponseType]特性针对同一状态码重复声明时,Swagger默认只会保留最后一个配置的返回类型。要实现多返回类型展示需要用到OpenAPI 3.0提供的oneOf语法,两种常见实现方案如下:

方案1:自定义特性 + Swagger过滤器(无第三方依赖)

该方案不需要引入额外NuGet包,适配所有支持OpenAPI 3.0的Swashbuckle版本。

步骤1:定义支持重复声明的多响应特性

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class MultipleProducesResponseTypeAttribute : Attribute
{
    public Type ResponseType { get; }
    public int StatusCode { get; }
    
    public MultipleProducesResponseTypeAttribute(Type responseType, int statusCode)
    {
        ResponseType = responseType;
        StatusCode = statusCode;
    }
}

步骤2:实现Swagger操作过滤器

过滤器负责读取自定义特性,将多个返回类型注入到对应状态码的oneOf配置中:

using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Reflection;

public class MultipleResponseTypesFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        var multiRespAttrs = context.MethodInfo
            .GetCustomAttributes<MultipleProducesResponseTypeAttribute>()
            .GroupBy(attr => attr.StatusCode);

        foreach (var statusGroup in multiRespAttrs)
        {
            var statusCode = statusGroup.Key.ToString();
            if (!operation.Responses.TryGetValue(statusCode, out var response))
            {
                response = new OpenApiResponse();
                operation.Responses.Add(statusCode, response);
            }

            var jsonContent = response.Content.TryGetValue("application/json", out var content) 
                ? content 
                : new OpenApiMediaType();
            
            jsonContent.Schema = new OpenApiSchema
            {
                OneOf = statusGroup.Select(attr => 
                    context.SchemaRepository.TryLookupByType(attr.ResponseType, out var schema) 
                        ? schema 
                        : context.SchemaGenerator.GenerateSchema(attr.ResponseType, context.SchemaRepository)
                ).ToList()
            };

            response.Content["application/json"] = jsonContent;
        }
    }
}

步骤3:注册过滤器到Swagger配置

在Program.cs(或Startup.cs)的Swagger服务注册逻辑中添加过滤器:

builder.Services.AddSwaggerGen(options =>
{
    // 你原有Swagger配置
    options.OperationFilter<MultipleResponseTypesFilter>();
});

步骤4:修改Action的特性声明

将原有重复的200状态码ProducesResponseType替换为自定义特性:

[HttpGet("{id}")]
[AllowAnonymous]
[MultipleProducesResponseType(typeof(PublicDto), StatusCodes.Status200OK)]
[MultipleProducesResponseType(typeof(PrivateDto), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(string), StatusCodes.Status403Forbidden)]
[ProducesResponseType(typeof(string), StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetUser(string id)
{
    // 原有业务逻辑保持不变
}

方案2:使用OneOf泛型类型(代码更简洁)

如果接受引入轻量级第三方包,Swashbuckle.AspNetCore 6.0+ 原生支持识别OneOf类型,自动生成oneOf配置。

步骤1:安装OneOf NuGet包

Install-Package OneOf

步骤2:修改Action的响应类型声明

直接将200状态码的返回类型设置为OneOf<PublicDto, PrivateDto>即可:

[HttpGet("{id}")]
[AllowAnonymous]
[ProducesResponseType(typeof(OneOf<PublicDto, PrivateDto>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(string), StatusCodes.Status403Forbidden)]
[ProducesResponseType(typeof(string), StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetUser(string id)
{
    // 原有业务逻辑保持不变
}

两种方案配置完成后,Swagger UI的200响应区域会出现下拉选择框,可切换查看PublicDto和PrivateDto的完整Schema定义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 03:18:04