mattfrear/Swashbuckle.AspNetCore.Filters

How to define two response examples for the same class

scrapstation opened this issue · 4 comments

The response model of 400 and 500 is the same class: RemoteServiceErrorInfo
But the example is different .
so, I defind two ExamplesProvider are as fallows

    [SwaggerResponse(200)]
    [SwaggerResponse(400, Type = typeof(RemoteServiceErrorInfo))]
    [SwaggerResponseExample(400, typeof(ClentErrorExamples))]
    [SwaggerResponse(500, Type = typeof(RemoteServiceErrorInfo))]
    [SwaggerResponseExample(500, typeof(ServerErrorExamples))]
    public class BaseApiController : ControllerBase
    {
    }
    public class ServerErrorExamples : IExamplesProvider<RemoteServiceErrorInfo>
    {
        public RemoteServiceErrorInfo GetExamples()
        {
            return new RemoteServiceErrorInfo
            {
                Code = "ServerErrorExamples"
            };
        }
    }
    public class ClentErrorExamples : IExamplesProvider<RemoteServiceErrorInfo>
    {
        public RemoteServiceErrorInfo GetExamples()
        {
            return new RemoteServiceErrorInfo
            {
                Code = "ClentErrorExamples"
            };
        }
    }

but the swagger shows the same example in 400 and 500
image

Hi, did you find a way? I have the same problem, one response class for different status codes

Sadness

image

Okay, i just implemented custom IOperationFilter because my responses the same for each method

My example:

public class ApiResponsesOperationFilter : IOperationFilter
    {
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            foreach (var response in operation.Responses)
            {
                if (int.TryParse(response.Key, out var httpCode))
                {
                    var content = response.Value.Content.FirstOrDefault();
                    if (content.Value is null) continue;
                    var example = GetApiError(httpCode);
                    if (example is null) continue;
                    content.Value.Example = new OpenApiString(JsonSerializer.Serialize(example));
                }
            }
        }
        public static ApiError? GetApiError(int httpCode) => httpCode switch
        {
            StatusCodes.Status401Unauthorized => new ApiError(httpCode, ErrorDescription.UnAuthorized, ErrorDescription.UnAuthorized),
            StatusCodes.Status403Forbidden => new ApiError(httpCode, ErrorDescription.Forbidden, ErrorDescription.Forbidden),
            StatusCodes.Status500InternalServerError => new ApiError(httpCode, ErrorDescription.Internal, ErrorDescription.Internal),
            _ => null
        };
    }

I can't reproduce this. I tried using @scrapstation's example:

namespace WebApi.Controllers
{
    [SwaggerResponse(200)]
    [SwaggerResponse(400, Type = typeof(RemoteServiceErrorInfo))]
    [SwaggerResponseExample(400, typeof(ClentErrorExamples))]
    [SwaggerResponse(500, Type = typeof(RemoteServiceErrorInfo))]
    [SwaggerResponseExample(500, typeof(ServerErrorExamples))]
    public class HomeController : ControllerBase
    {
        [HttpGet("home/index")]
        public IActionResult Index()
        {
            return NoContent();
        }
    }

    public class ServerErrorExamples : IExamplesProvider<RemoteServiceErrorInfo>
    {
        public RemoteServiceErrorInfo GetExamples()
        {
            return new RemoteServiceErrorInfo
            {
                Code = "ServerErrorExamples"
            };
        }
    }

    public class RemoteServiceErrorInfo
    {
        public string Code { get; internal set; }
    }

    public class ClentErrorExamples : IExamplesProvider<RemoteServiceErrorInfo>
    {
        public RemoteServiceErrorInfo GetExamples()
        {
            return new RemoteServiceErrorInfo
            {
                Code = "ClentErrorExamples"
            };
        }
    }
}

and this is what I get:
image

If someone can provide example code which I can copy and paste to reproduce, I can investigate further.