我想准备我的.NET Core Web API项目,以便可以根据 REST 服务标准管理和记录 API 的多个版本。
我正在使用.NET Core 2.1和NSwag (v11.18.2)。我还安装了Microsoft.AspNetCore.Mvc.Versioning NuGet 包。
我已经用谷歌搜索了一些配置示例,但我发现唯一有用的链接是这个。
我现在可以获取两个 API 版本的 Swagger 页面,但存在一些问题:
- 请注意,最后的
config
设置(Title
、Description
等)都不会对 2 条路线中的任何一条生效。它仅在我将它们添加到每个单独的配置时才有效。所以我也想知道是否可以避免这种情况,因为 API 的一般配置可以是版本独立的(标题、描述等......)。 - 由于上面链接中讨论的 NSwag 和 Microsoft API 版本控制包的问题是在 2-3 个月前打开的(以及 NSwag 版本),我想知道它现在是否真正得到修复,在这种情况下,这是要设置的正确配置。
- 虽然版本在控制器的配置中是明确的,但它仍然是控制器方法的强制输入参数,当然我不希望这样!见图片:
因此,按照该示例,我的实际配置如下所示:
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 ...
}
}