昂首阔步找不到ApiVersion版本的动作 [英] Swagger not finding ApiVersion-ed actions

查看:108
本文介绍了昂首阔步找不到ApiVersion版本的动作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在ASP.NET Core中构建Web API,并正在尝试使用多个版本.我正在按照以下说明为每个版本创建Swagger文档: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/README.md#customize-the-action-selection-process

I'm building a Web API in ASP.NET Core and am experimenting with multiple versions. I am creating Swagger docs for each version following these instructions: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/README.md#customize-the-action-selection-process

我为同一个动作定义了2个版本,如下所示:

I have 2 versions of the same action defined like this:

namespace Web.Api
{
    [ApiController]
    [Area("api")]
    [Route("[area]/[controller]")]
    public abstract class MyApiControllerBase : ControllerBase
    {

    }
}

namespace Web.Api.V1
{
    public class TestController : MyApiControllerBase
    {
        [HttpGet]
        [ApiVersion("1.0")]
        public IActionResult Get()
        {
            return Ok("Version 1.0 endpoint.");
        }
    }
}

namespace Web.Api.V2
{
    public class TestController : MyApiControllerBase
    {
        [HttpGet]
        [ApiVersion("2.0")]
        public IActionResult Get()
        {
            return Ok("Version 2.0 endpoint.");
        }
    }
}

我的Swagger Gen在 Startup.cs 中配置如下:

And my Swagger Gen configured like this in Startup.cs:

services.AddSwaggerGen(options =>
{
    options.DocInclusionPredicate((docName, apiDesc) =>
    {
        if (!apiDesc.TryGetMethodInfo(out MethodInfo methodInfo))
        {
            return false;
        }

        IEnumerable<ApiVersion> versions = methodInfo.DeclaringType
            .GetCustomAttributes(true)
            .OfType<ApiVersionAttribute>()
            .SelectMany(a => a.Versions);

        return versions.Any(v => $"v{v.ToString()}" == docName);
    });

    options.SwaggerDoc("v1.0", new OpenApiInfo { Title = "My API", Version = "v1.0" });
    options.SwaggerDoc("v2.0", new OpenApiInfo { Title = "My API", Version = "v2.0" });
});

但是,当我访问Swagger UI时,它说规范中未定义任何操作!"对于v1.0和v2.0.如果在加载Swagger文档时检查 DocInclusionPredicate ,似乎未选择 ApiVersion 属性,从而解释了为什么未将其包含在文档中.例如,当 Web.Api.V2.TestController.Get 作为 apiDesc 参数传递时,这就是对属性的发现:

However when I visit my Swagger UI it says "No operations defined in spec!" for both v1.0 and v2.0. If I inspect the DocInclusionPredicate when loading the Swagger doc it appears that the ApiVersion Attribute isn't being picked up and thus explains why they aren't included in the docs. For example, when Web.Api.V2.TestController.Get is passed as the apiDesc argument, this is what is found for Attributes:

属性

ApiControllerAttribute , AreaAttribute RouteAttribute ControllerAttribute .所有这些都是基类上的属性,而不是直接在 TestController Get()操作本身上.

Only ApiControllerAttribute, AreaAttribute, RouteAttribute, and ControllerAttribute are found. All of these are Attributes on base classes, not directly on the TestController or Get() action itself.

推荐答案

对于asp.net core 3.0,您可以按照以下步骤操作:

For asp.net core 3.0,you could follow the following steps:

1.安装 Swashbuckle.AspNetCore 5.0.0

1.Install Swashbuckle.AspNetCore 5.0.0

2.安装 Microsoft.AspNetCore.Mvc版本4.0.0

2.Install Microsoft.AspNetCore.Mvc.Versioning 4.0.0

3.安装 Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer 4.0.0

3.Install Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer 4.0.0

4.如下更改控制器( ApiVersion 需要在控制器上声明)

4.Change your controller like below(ApiVersion needs to be declared on controller):

[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("1.0")]
public class TestController : MyApiControllerBase
{
    [HttpGet]      
    public IActionResult Get()
    {
        return Ok("Version 1.0 endpoint.");
    }
}
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("2.0")]
public class TestController : MyApiControllerBase
{
    [HttpGet]        
    public IActionResult Get()
    {
        return Ok("Version 2.0 endpoint.");
    }
}

5.Startup.cs(请注意,您需要使用 services.AddVersionedApiExplorer 并设置 options.SubstituteApiVersionInUrl = true 告诉大摇大摆来替换控制器路由中的版本并配置api版本:):

5.Startup.cs(Note that 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: ):

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    services.AddApiVersioning(o => {
        o.ReportApiVersions = true;
        o.AssumeDefaultVersionWhenUnspecified = true;
        o.DefaultApiVersion = new ApiVersion(1, 0);
    });
    services.AddVersionedApiExplorer(o =>
    {
        o.GroupNameFormat = "'v'VVV";
        o.SubstituteApiVersionInUrl = true;
    });

    services.AddSwaggerGen(options =>
    {
        options.DocInclusionPredicate((docName, apiDesc) =>
        {
            if (!apiDesc.TryGetMethodInfo(out MethodInfo methodInfo))
            {
                return false;
            }

            IEnumerable<ApiVersion> versions = methodInfo.DeclaringType
                .GetCustomAttributes(true)
                .OfType<ApiVersionAttribute>()
                .SelectMany(a => a.Versions);

            return versions.Any(v => $"v{v.ToString()}" == docName);
        });

        options.SwaggerDoc("v1.0", new OpenApiInfo { Title = "My API", Version = "v1.0" });
        options.SwaggerDoc("v2.0", new OpenApiInfo { Title = "My API", Version = "v2.0" });
    });
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseHttpsRedirection();
    app.UseApiVersioning();
    app.UseSwagger();
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1.0/swagger.json", "V1 Docs");
        c.SwaggerEndpoint("/swagger/v2.0/swagger.json", "V2 Docs");
    });

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

这篇关于昂首阔步找不到ApiVersion版本的动作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆