8

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

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

我已经用谷歌搜索了一些配置示例,但我发现唯一有用的链接是这个

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

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

Swagger UI 测试需要版本作为方法的输入参数

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

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 ...
    }
}
4

2 回答 2

3
  1. 它们在中间件中被忽略,因为它们是从设置中推断出来的,或者不适用于 api explorer(模板)。但是标题和描述应该有效......
  2. 请创建一个带有特定问题的问题和一个 repro,同时查看 repo 中的现有测试
  3. 已在 v11.18.3 中修复
于 2018-08-08T17:15:39.077 回答
3

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

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

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

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

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

于 2018-12-23T02:23:54.303 回答