Search code examples
asp.net-core-webapiswagger-uinswag

Calling versioned endpoints via accept header using SwaggerUI and nSwag


I've got an ASP.NET Core 6.0 web app that uses versioned endpoints. I've selected to use the MediaTypeApiVersionReader, which means the api version is passed in the accept header of the request.

I'm using nSwag v13.19.0 for the Swagger pipeline, and SwaggerUI to render the swagger UI.

The swagger UI page is rendering both versions of my API, but the MediaType dropdown on the swagger UI isn't include the selected version. Swagger UI showing missing version informationin the media type dropdown.

As a result of the missing version information, the swagger UI always executes the default version of the endpoint.

How can I configure Nswag to include the version number in the media type drop down so I can specify the correct version?


Solution

  • Here is the test result;

    enter image description here

    Let me share my test project structure.

    enter image description here

    CustomMediaTypeProcessor.cs file

    using NSwag.Generation.Processors.Contexts;
    using NSwag.Generation.Processors;
    
    namespace WebApplication1
    {
        public class CustomMediaTypeProcessor : IOperationProcessor
        {
            public bool Process(OperationProcessorContext context)
            {
                foreach (var response in context.OperationDescription.Operation.Responses.Values)
                {
                    foreach (var mediaType in response.Content.Keys.ToList())
                    {
                        if (mediaType == "application/json")
                        {
                            response.Content[$"application/json;Version={context.Document.Info.Version}"] = response.Content[mediaType];
                            response.Content.Remove(mediaType);
                        }
                    }
                }
    
                return true;
            }
        }
    }
    

    Program.cs

    using System.Reflection.Metadata;
    
    namespace WebApplication1
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                var builder = WebApplication.CreateBuilder(args);
    
                // Add services to the container.
    
                builder.Services.AddControllers();
                builder.Services.AddOpenApiDocument(config =>
                {
                    //// Other configuration
    
                    config.OperationProcessors.Add(new CustomMediaTypeProcessor()); // Register the custom processor
                    config.PostProcess = document =>
                    {
                        document.Info.Version = "v1";
                        document.Info.Title = "Title ";
                        document.Info.Description = "API ";
                        document.Info.TermsOfService = "None";
    
                    };
                });
    
    
                var app = builder.Build();
    
                if (app.Environment.IsDevelopment())
                {
                    // Add OpenAPI 3.0 document serving middleware
                    // Available at: http://localhost:<port>/swagger/v1/swagger.json
                    app.UseOpenApi();
    
                    // Add web UIs to interact with the document
                    // Available at: http://localhost:<port>/swagger
                    app.UseSwaggerUi3();
                }
    
                // Configure the HTTP request pipeline.
    
                app.UseHttpsRedirection();
    
                app.UseAuthorization();
    
    
                app.MapControllers();
    
                app.Run();
            }
        }
    }