Наконец удалось исправить проблемы, и вот полные настройки
Первое, что нужно сделать, это установить следующие пакеты
• Microsoft.AspNetCore. Mvc .Versioning
• Swashbuckle.AspNetCore
• Swashbuckle.Core
Two controllers one for each version
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("1")]
[ApiController]
public class VtestController : ControllerBase
{
[HttpGet]
// Which version the route corresponds to
[MapToApiVersion("1")]
[Route("Mangoes")]
public string GetMangoes() => "Mangoes v1";
}
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("2")]
[ApiController]
public class VtestController : ControllerBase
{
[HttpGet]
// Which version the route corresponds to
[MapToApiVersion("2")]
[Route("Mangoes")]
public string GetMangoes() => "Mangoes v2";
}
Код Startp.cs, связанный с включением версий и чванством. ниже настройка, относящаяся к configuservice и коду конфигурации
public void ConfigureServices(IServiceCollection services)
{
services.AddApiVersioning(o =>
{
o.AssumeDefaultVersionWhenUnspecified = true;
o.DefaultApiVersion = new ApiVersion(1, 0);
});
//swagger
// Register the Swagger generator, defining 1 or more Swagger documents
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1",
new OpenApiInfo
{
Title = " API v1",
Version = "v1"
});
// Add a SwaggerDoc for v2
options.SwaggerDoc(
"v2",
new OpenApiInfo
{
Title = " API v2",
Version = "v2"
});
// Apply the filters
options.OperationFilter<RemoveVersionFromParameter>();
options.DocumentFilter<ReplaceVersionWithExactValueInPath>();
// Ensure the routes are added to the right Swagger doc
options.DocInclusionPredicate((version, desc) =>
{
if (!desc.TryGetMethodInfo(out MethodInfo methodInfo))
return false;
var versions = methodInfo.DeclaringType
.GetCustomAttributes(true)
.OfType<ApiVersionAttribute>()
.SelectMany(attr => attr.Versions);
var maps = methodInfo
.GetCustomAttributes(true)
.OfType<MapToApiVersionAttribute>()
.SelectMany(attr => attr.Versions)
.ToArray();
return versions.Any(v => $"v{v.ToString()}" == version)
&& (!maps.Any() || maps.Any(v => $"v{v.ToString()}" == version));
});
});
}
Swashbuckle не знает, что есть разница в двух маршрутах - он видит их как один и тот же. Так что давайте поможем Swashbuckle. Для этого нам нужно создать два класса:
public class RemoveVersionFromParameter : Swashbuckle.AspNetCore.SwaggerGen.IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var versionParameter = operation.Parameters.Single(p => p.Name == "version");
operation.Parameters.Remove(versionParameter);
}
}
и
public class ReplaceVersionWithExactValueInPath : Swashbuckle.AspNetCore.SwaggerGen.IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
var paths = new OpenApiPaths();
foreach (var path in swaggerDoc.Paths)
{
paths.Add(path.Key.Replace("v{version}", swaggerDoc.Info.Version), path.Value);
}
swaggerDoc.Paths = paths;
}
}
часть конфигурации
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint($"/swagger/v1/swagger.json", $"API v1");
// Specify and endpoint for v2
c.SwaggerEndpoint($"/swagger/v2/swagger.json", $"API v2");
});
}