настройка Swagger для поддержки конечных точек API с поддержкой версий в ASP. NET Core 3.1 - PullRequest
0 голосов
/ 05 августа 2020

Наконец удалось исправить проблемы, и вот полные настройки

Первое, что нужно сделать, это установить следующие пакеты

• 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");
        });


     }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...