【问题标题】:NSwag .NET Core API Versioning configurationNSwag .NET Core API 版本控制配置
【发布时间】:2019-01-13 13:49:47
【问题描述】:

我想准备我的 .NET Core Web API 项目,以便可以根据 REST 服务标准管理和记录 API 的多个版本。

我正在使用 .NET Core 2.1NSwag (v11.18.2)。我还安装了 Microsoft.AspNetCore.Mvc.Versioning NuGet 包。

我已经用 Google 搜索了一些配置示例,但我找到的唯一有用的链接是 this

我现在可以获取两个 API 版本的 Swagger 页面,但存在一些问题:

  1. 请注意,最后的config 设置(TitleDescription 等)都不会对 2 条路由中的任何一条生效。它仅在我将它们添加到每个单独的配置时才有效。所以我也想知道是否可以避免这种情况,因为 API 的一般配置可以是版本独立的(标题、描述等......)。
  2. 由于上面链接中讨论的 NSwag 和 Microsoft API 版本控制包的问题是在 2-3 个月前打开的(以及 NSwag 版本),我想知道它现在是否真正得到修复,在这种情况下,这是正确的配置。
  3. 虽然版本在控制器的配置中是明确的,但它仍然是控制器方法的强制输入参数,我当然不希望这样!见图片:

因此,按照该示例,我的实际配置如下所示:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services.AddApiVersioning(options =>
        {
            options.AssumeDefaultVersionWhenUnspecified = true;
            options.DefaultApiVersion = new ApiVersion(1, 0);
            options.ReportApiVersions = true;
        });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseSwaggerWithApiExplorer(config =>
    {
        config.GeneratorSettings.OperationProcessors.TryGet<ApiVersionProcessor>().IncludedVersions = new[] { "1.0" };
        config.SwaggerRoute = "v1.0.json";
    });

    app.UseSwaggerWithApiExplorer(config =>
    {
        config.GeneratorSettings.OperationProcessors.TryGet<ApiVersionProcessor>().IncludedVersions = new[] { "2.0" };
        config.SwaggerRoute = "v2.0.json";
    });

    app.UseSwaggerUi3(typeof(Startup).GetTypeInfo().Assembly, config =>
    {
        config.SwaggerRoutes.Add(new SwaggerUi3Route("v1.0", "/v1.0.json"));
        config.SwaggerRoutes.Add(new SwaggerUi3Route("v2.0", "/v2.0.json"));

        config.GeneratorSettings.Title = "My API";
        config.GeneratorSettings.Description = "API functionalities.";
        config.GeneratorSettings.DefaultUrlTemplate = "{v:apiVersion}/{controller}/{action}/{id?}";
        config.GeneratorSettings.DefaultPropertyNameHandling = PropertyNameHandling.CamelCase
    });
}

这些是我的实际控制者:

[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]/[action]")]
[SwaggerTag("Test1", Description = "Core operations on machines (v1.0).")]
public class MachinesController : Controller
{
    [HttpGet("{id}")]
    [ProducesResponseType((int)HttpStatusCode.OK)]
    public async Task<ActionResult<Machine>> Get(int id)
    {
        return await ...
    }
}

[ApiController]
[ApiVersion("2.0")]
[Route("api/v{version:apiVersion}/[controller]/[action]")]
[SwaggerTag("Test2", Description = "Core operations on machines (v2.0).")]
public class MachinesController : Controller
{
    [HttpGet("{id}")]
    [ProducesResponseType((int)HttpStatusCode.OK)]
    public async Task<ActionResult<Machine>> Get(int id)
    {
        return await ...
    }
}

【问题讨论】:

    标签: c# .net-core asp.net-core-webapi api-versioning nswag


    【解决方案1】:
    1. 它们在中间件中被忽略,因为它们是从设置中推断出来的,或者不适用于 api explorer(模板)。但是标题和描述应该可以工作...
    2. 请创建一个包含特定问题和重现的问题,同时查看 repo 中的现有测试
    3. 已在 v11.18.3 中修复

    【讨论】:

    • 问题 n。 3:修复!谢谢! 问题 n. 2:我打开了一个问题here,但只是为了一个建议。希望它可以以某种方式有用! 问题 n. 1:仍然存在,并且标题和描述不起作用。当您说“它们在中间件中被忽略,因为它们是从设置中推断出来的......”时,您是什么意思?
    • API Explorer 不支持 DefaultUrlTemplate,因为您必须为每个操作指定路由,否则 API Explorer 不会拾取它。 DefaultPropertyNameHandling 被忽略并从 Newtonsoft.Json 序列化程序设置中读取(您不必自己设置)。标题和描述一定是个bug,你也可以为此创建一个问题吗?
    • 感谢您的提示。添加了新的issue
    【解决方案2】:

    我相信从 NSwag 12.0.0 开始,对 API Explorer 的支持有了显着改进。重要的是还引用了补充的 API Explorer package for API versioning,以便向 NSwag 提供正确的信息。

    API Versioning 提供的Swagger sample application 使用 Swashbuckle,但设置将与 NSwag 非常相似。您可以使用 IApiVersionDescriptionProvider 服务来枚举您的应用程序中定义的所有 API 版本。这应该会大大简化您的 NSwag 配置。

    您正在按 URL 段进行版本控制;因此,要解决问题 3,您只需简单地配置 API Explorer:

    services.AddVersionedApiExplorer( options => options.SubstituteApiVersionInUrl = true );
    

    这会将路由模板中的{version}路由参数替换为对应的API版本值,并从API描述中删除API版本参数。

    【讨论】:

    • 嗨,Chris,您能提供一个使用 IApiVersionDescriptionProvider 的代码示例吗?我的设置正常工作,但我使用 services.AddSwaggerDocument() 手动添加文档,但这涉及手动添加每个版本的文档。我知道如何使用 IApiVersionDescriptionProvider 添加路由,但这不会添加实际文档?根据github.com/RicoSuter/NSwag/issues/1760@Rico Suter 声明“UseSwaggerUi3() 仅配置 UI 和要使用的文档”。如何自动添加文档?
    • 您是否使用了我提供的链接中的 Swagger 示例应用程序?样品的确切位置在这里:github.com/Microsoft/aspnet-api-versioning/blob/master/samples/…IApiVersionDescriptionProvider 由 API 版本控制提供。您直接通过 DI 或通过 DI 组合隐式请求它。此服务将为您提供要添加的 Swagger 端点的元数据信息,包括:API 版本、组名称以及该版本是否已弃用。
    • API Explorer 将按 API 的 GroupName 整理 API,这是按照您想要的方式格式化的 API 版本,通常是它在 Swagger 端点路由中的显示方式。我知道 Swashbuckle 在生成 Swagger 文档时使用 GroupName 对操作进行分组。我不确定NSwag。如果它不能自动执行,您可以使用在该属性上分组的 LINQ 查询自己轻松完成。
    • 如果我做 'services.AddSwaggerDocument();'在“ConfigureServices()”中,然后在“Configure()”中使用 IApiVersionDescriptionProvider 添加诸如“config.SwaggerRoutes.Add(new SwaggerUi3Route($"v{description.GroupName}", $"/v{description.GroupName} .json"));"只有“/swagger/v1/swagger.json”有效,它包含所有方法(v1 和 v2)。你想让我打开一个问题,以便我提供代码示例吗?
    • 嗨,克里斯。抱歉,我是个白痴……我设法通过使用 DI "var provider = services.BuildServiceProvider().GetRequiredService();" 在 ConfigureServices() 中获取接口来使其工作
    猜你喜欢
    • 2021-09-11
    • 2019-11-19
    • 2016-12-17
    • 1970-01-01
    • 1970-01-01
    • 2014-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多