Skip to content

Swagger add API versioning

Install package Asp.Versioning.Mvc 8.1.0

In Utilities, add SwaggerGenVersion.cs

csharp
public class SwaggerGenVersion : IConfigureNamedOptions<SwaggerGenOptions>
{
    private readonly IApiVersionDescriptionProvider _provider;

    public SwaggerGenVersion(IApiVersionDescriptionProvider provider)
    {
        _provider = provider;
    }

    public void Configure(SwaggerGenOptions options)
    {
        foreach (var description in _provider.ApiVersionDescriptions)
        {
            options.SwaggerDoc(description.GroupName, CreateVersionInfo(description));
        }
    }

    public void Configure(string? name, SwaggerGenOptions options)
    {
        Configure(options);
    }

    private OpenApiInfo CreateVersionInfo(
        ApiVersionDescription desc)
    {
        var info = new OpenApiInfo
        {
            Title = "Library",
            Version = desc.ApiVersion.ToString()
        };

        if (desc.IsDeprecated)
        {
            info.Description +=
                " This API version has been deprecated. Please use one of the new APIs available from the explorer.";
        }

        return info;
    }
}


In Utilities, add EndpointConfigurator.cs

csharp
public static class EndpointConfigurator
{
    public static void ConfigureSwagger(this WebApplicationBuilder builder)
    {
        var apiVersioningBuilder = builder.Services.AddApiVersioning(options =>
        {
            // in API response header, there will be api-supported-version showing available versions, eg 1.0, 2.0
            options.ReportApiVersions = true;
            options.DefaultApiVersion = new ApiVersion(1, 0);
            options.AssumeDefaultVersionWhenUnspecified = true;
        });

        // add the versioned api explorer, which also adds IApiVersionDescriptionProvider service
        apiVersioningBuilder.AddApiExplorer(options =>
        {
            // format the version as "'v'major[.minor][-status]"
            options.GroupNameFormat = "'v'VVV";

            // only necessary when versioning by url segment
            // can also be used to control the format of the API version in route templates
            options.SubstituteApiVersionInUrl = true;
        });
        
        // generate swagger.json for each version
        // without this, in Swagger top right, when choose v2 etc, it shows "Failed to load API definition."
        builder.Services.ConfigureOptions<SwaggerGenVersion>();
    }
}


In Program.cs, call builder.ConfigureSwagger();

csharp
//...

builder.ConfigureSwagger();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

//...


In Program.cs

csharp
app.UseSwaggerUI(c =>
{
    var provider = app.Services.GetService<IApiVersionDescriptionProvider>();
    foreach (var description in provider.ApiVersionDescriptions)
    {
        c.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
    }
});


On controllers, use [Route("/v{version:apiVersion}/[controller]")]

On actions, use [ApiVersion("1.0")]

To make endpoint not appear in Swagger, use [ApiExplorerSettings(IgnoreApi = true)]

Released under the MIT License.