Swagger 未找到 ApiVersion ed 操作

2024-02-25

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

我有两个版本的相同操作定义如下:

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:

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。如果我检查DocInclusionPredicate加载 Swagger 文档时,似乎ApiVersion属性没有被选取,因此解释了为什么它们没有包含在文档中。例如,当Web.Api.V2.TestController.Get被传递为apiDesc参数,这是属性的内容:

属性 https://i.stack.imgur.com/Y76YP.png

Only ApiControllerAttribute, AreaAttribute, RouteAttribute, and ControllerAttribute被发现。所有这些都是基类的属性,而不是直接在TestController or Get()行动本身。


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

1.安装Swashbuckle.AspNetCore 5.0.0 https://www.nuget.org/packages/Swashbuckle.AspNetCore/

2.安装Microsoft.AspNetCore.Mvc.Versioning 4.0.0 https://www.nuget.org/packages/Microsoft.AspNetCore.Mvc.Versioning/4.0.0

3.安装Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer 4.0.0 https://www.nuget.org/packages/Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer/4.0.0

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

[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告诉 swagger 替换控制器路由中的版本并配置 api 版本:):

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();
    });
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Swagger 未找到 ApiVersion ed 操作 的相关文章

  • Qt-Qlist 检查包含自定义类

    有没有办法覆盖加载自定义类的 Qt QList 的比较机制 即在 java 中你只需要重写一个比较方法 我有一个带有我的自定义类模型的 QList QList
  • 从父类调用子类方法

    a doStuff 方法是否可以在不编辑 A 类的情况下打印 B did stuff 如果是这样 我该怎么做 class Program static void Main string args A a new A B b new B a
  • Newtonsoft JSON PreserveReferences处理自定义等于用法

    我目前在使用 Newtonsoft Json 时遇到一些问题 我想要的很简单 将要序列化的对象与所有属性和子属性进行比较以确保相等 我现在尝试创建自己的 EqualityComparer 但它仅与父对象的属性进行比较 另外 我尝试编写自己的
  • 当 contains() 工作正常时,xpath 函数ends-with() 工作时出现问题

    我正在尝试获取具有以特定 id 结尾的属性的标签 like span 我想获取 id 以 国家 地区 结尾的跨度我尝试以下xpath span ends with id Country 但我得到以下异常 需要命名空间管理器或 XsltCon
  • ASP.NET Core Tag Helper Checkbox 不保存未选中的值

    我正在使用标签帮助程序在 MVC 表单中添加一个复选框 div class form group div
  • WPF 中的调度程序和异步等待

    我正在尝试学习 WPF C 中的异步编程 但我陷入了异步编程和使用调度程序的困境 它们是不同的还是在相同的场景中使用 我愿意简短地回答这个问题 以免含糊不清 因为我知道我混淆了 WPF 中的概念和函数 但还不足以在功能上正确使用它 我在这里
  • C#:如何防止主窗体过早显示

    在我的 main 方法中 我像往常一样启动主窗体 Application EnableVisualStyles Application SetCompatibleTextRenderingDefault false Application
  • Qt moc 在头文件中实现?

    是否可以告诉 Qt MOC 我想声明该类并在单个文件中实现它 而不是将它们拆分为 h 和 cpp 文件 如果要在 cpp 文件中声明并实现 QObject 子类 则必须手动包含 moc 文件 例如 文件main cpp struct Sub
  • 使用 System.Text.Json 即时格式化 JSON 流

    我有一个未缩进的 Json 字符串 例如 hash 123 id 456 我想缩进字符串并将其序列化为 JSON 文件 天真地 我可以使用缩进字符串Newtonsoft如下 using Newtonsoft Json Linq JToken
  • 如何返回 json 结果并将 unicode 字符转义为 \u1234

    我正在实现一个返回 json 结果的方法 例如 public JsonResult MethodName Guid key var result ApiHelper GetData key Data is stored in db as v
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • 将自定义元数据添加到 jpeg 文件

    我正在开发一个图像处理项目 C 我需要在处理完成后将自定义元数据写入 jpeg 文件 我怎样才能做到这一点 有没有可用的图书馆可以做到这一点 如果您正在谈论 EXIF 元数据 您可能需要查看exiv2 http www exiv2 org
  • clang 实例化后静态成员初始化

    这样的代码可以用 GCC 编译 但 clang 3 5 失败 include
  • 从库中捕获主线程 SynchronizationContext 或 Dispatcher

    我有一个 C 库 希望能够将工作发送 发布到 主 ui 线程 如果存在 该库可供以下人员使用 一个winforms应用程序 本机应用程序 带 UI 控制台应用程序 没有 UI 在库中 我想在初始化期间捕获一些东西 Synchronizati
  • 当操作繁忙时,表单不执行任何操作(冻结)

    我有一个使用 C 的 WinForms 应用程序 我尝试从文件中读取一些数据并将其插入数据表中 当此操作很忙时 我的表单冻结并且无法移动它 有谁知道我该如何解决这个问题 这可能是因为您在 UI 线程上执行了操作 将文件和数据库操作移至另一个
  • 如何在 VBA 中声明接受 XlfOper (LPXLOPER) 类型参数的函数?

    我在之前的回答里发现了问题 https stackoverflow com q 19325258 159684一种无需注册即可调用 C xll 中定义的函数的方法 我之前使用 XLW 提供的注册基础结构 并且使用 XlfOper 类型在 V
  • 将文本叠加在图像背景上并转换为 PDF

    使用 NET 我想以编程方式创建一个 PDF 它仅包含一个背景图像 其上有两个具有不同字体和位置的标签 我已阅读过有关现有 PDF 库的信息 但不知道 如果适用 哪一个对于如此简单的任务来说最简单 有人愿意指导我吗 P D 我不想使用生成的
  • 在 Dynamics CRM 插件中访问电子邮件发件人地址

    我正在编写一个 Dynamics CRM 2011 插件 该插件挂钩到电子邮件实体的更新后事件 阶段 40 pipeline http msdn microsoft com en us library gg327941 aspx 并且在此阶
  • ASP.NET MVC 6 (ASP.NET 5) 中的 Application_PreSendRequestHeaders 和 Application_BeginRequest

    如何在 ASP NET 5 MVC6 中使用这些方法 在 MVC5 中 我在 Global asax 中使用了它 现在呢 也许是入门班 protected void Application PreSendRequestHeaders obj
  • 限制C#中的并行线程数

    我正在编写一个 C 程序来生成并通过 FTP 上传 50 万个文件 我想并行处理4个文件 因为机器有4个核心 文件生成需要更长的时间 是否可以将以下 Powershell 示例转换为 C 或者是否有更好的框架 例如 C 中的 Actor 框

随机推荐