Mathias Rönnlund
Mathias Rönnlund

Reputation: 4855

How do I get Swashbuckle to work in Asp.net Core 3.1 when using VersionByNamespaceConvention?

I'm using VersionByNamespaceConvention. In Startup.cs in ConfigureServices I added:

        services.AddApiVersioning(options =>
        {
            options.Conventions.Add(new VersionByNamespaceConvention());
        });

        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
            c.SwaggerDoc("v2", new OpenApiInfo { Title = "My API", Version = "v2" });
        });

and in Configure

        app.UseSwagger();

        // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
        // specifying the Swagger JSON endpoint.
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
            c.SwaggerEndpoint("/swagger/v2/swagger.json", "My API V2");
        });

In the root of the project I have folders v1 and v2 and under those I have a Controllers folder. The code of the controllers (v2 is identical to v1, except for the namespace and the return value).

namespace WebApitest.v1.Controllers
{
    [ApiController]
    [Route("v{version:apiVersion}/[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        [HttpGet]
        public string Get()
        {
            return "v1";
        }
    }
}

The api itself is working good, but Swagger rendering is not working as expected.

When opening https://localhost:44307/swagger/index.html it shows a dropdown in the top right corner showing "My API V1" and "My API V2" but the middle of the screen is showing

Fetch error - undefined /swagger/v1/swagger.json

This works if I only have controllers in the v1 version. But then it is showing the version number like in the image below, even though the version number here is already selected.

enter image description here

The solution

I added the nuget package Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer v4.x and added the following code to ConfigureServices and now it's working as expected.

        services.AddVersionedApiExplorer(o =>
        {
            o.GroupNameFormat = "'v'VVV";
            o.SubstituteApiVersionInUrl = true;
        });

Upvotes: 1

Views: 2058

Answers (1)

Rena
Rena

Reputation: 36705

You need to use services.AddVersionedApiExplorer and set options.SubstituteApiVersionInUrl=true to tell swagger to replace the version in the controller route and configure the api version:

services.AddVersionedApiExplorer(o =>
{
      o.GroupNameFormat = "'v'VVV";
      o.SubstituteApiVersionInUrl = true;
});

Result: enter image description here

Upvotes: 2

Related Questions