问题描述
我们有 asp.net 核心 webapi.我们添加了 Microsoft.AspNetCore.Mvc.Versioning
和 Swashbuckle
以拥有 swagger UI.我们将控制器指定为:
We have asp.net core webapi. We added Microsoft.AspNetCore.Mvc.Versioning
and Swashbuckle
to have swagger UI.
We specified controllers as this:
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
public class ContactController : Controller
{
当我们运行 swagger ui 时,我们会在路由中获取版本作为参数:
When we run swagger ui we get version as parameter in routes:
如何为路由设置默认的v1"?如果版本 2 上台,两个版本如何支持 swagger ui?
How to set-up default "v1" for route ? If version 2 come to the stage how support swagger ui for both versions ?
推荐答案
目前 Swashbuckle 和 Microsoft.AspNetCore.Mvc.Versioning 是朋友.它运作良好.我刚刚在 VS2017 中创建了测试项目并检查了它是如何工作的.
At the moment Swashbuckle and Microsoft.AspNetCore.Mvc.Versioning are friends. It works good. I just created test project in VS2017 and checked how it works.
首先包含这两个nuget包:
First include these two nuget packages:
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="1.2.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="1.0.0" />
在 Startup.cs
中配置所有内容(阅读我的评论):
Configure everything in Startup.cs
(read my comments):
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
// Configure versions
services.AddApiVersioning(o =>
{
o.AssumeDefaultVersionWhenUnspecified = true;
o.DefaultApiVersion = new ApiVersion(1, 0);
});
// Configure swagger
services.AddSwaggerGen(options =>
{
// Specify two versions
options.SwaggerDoc("v1",
new Info()
{
Version = "v1",
Title = "v1 API",
Description = "v1 API Description",
TermsOfService = "Terms of usage v1"
});
options.SwaggerDoc("v2",
new Info()
{
Version = "v2",
Title = "v2 API",
Description = "v2 API Description",
TermsOfService = "Terms of usage v2"
});
// This call remove version from parameter, without it we will have version as parameter
// for all endpoints in swagger UI
options.OperationFilter<RemoveVersionFromParameter>();
// This make replacement of v{version:apiVersion} to real version of corresponding swagger doc.
options.DocumentFilter<ReplaceVersionWithExactValueInPath>();
// This on used to exclude endpoint mapped to not specified in swagger version.
// In this particular example we exclude 'GET /api/v2/Values/otherget/three' endpoint,
// because it was mapped to v3 with attribute: MapToApiVersion("3")
options.DocInclusionPredicate((version, desc) =>
{
var versions = desc.ControllerAttributes()
.OfType<ApiVersionAttribute>()
.SelectMany(attr => attr.Versions);
var maps = desc.ActionAttributes()
.OfType<MapToApiVersionAttribute>()
.SelectMany(attr => attr.Versions)
.ToArray();
return versions.Any(v => $"v{v.ToString()}" == version) && (maps.Length == 0 || maps.Any(v => $"v{v.ToString()}" == version));
});
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint($"/swagger/v2/swagger.json", $"v2");
c.SwaggerEndpoint($"/swagger/v1/swagger.json", $"v1");
});
app.UseMvc();
}
有两个类可以解决问题:
There two classes that make the trick:
public class RemoveVersionFromParameter : IOperationFilter
{
public void Apply(Operation operation, OperationFilterContext context)
{
var versionParameter = operation.Parameters.Single(p => p.Name == "version");
operation.Parameters.Remove(versionParameter);
}
}
public class ReplaceVersionWithExactValueInPath : IDocumentFilter
{
public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
{
swaggerDoc.Paths = swaggerDoc.Paths
.ToDictionary(
path => path.Key.Replace("v{version}", swaggerDoc.Info.Version),
path => path.Value
);
}
}
RemoveVersionFromParameter
从 swagger UI 中移除这个文本框:
The RemoveVersionFromParameter
removes from swagger UI this textbox:
ReplaceVersionWithExactValueInPath
改变这个:
到这里:
Controller 类现在如下所示:
Controller class looks now as follows:
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("1")]
[ApiVersion("2")]
public class ValuesController : Controller
{
// GET api/values
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
[HttpGet("{id}")]
public string Get(int id)
{
return "value";
}
// POST api/values
[HttpPost]
public void Post([FromBody]string value)
{
}
// PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/values/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
[HttpGet("otherget/one")]
[MapToApiVersion("2")]
public IEnumerable<string> Get2()
{
return new string[] { "value1", "value2" };
}
/// <summary>
/// THIS ONE WILL BE EXCLUDED FROM SWAGGER Ui, BECAUSE v3 IS NOT SPECIFIED. 'DocInclusionPredicate' MAKES THE
/// TRICK
/// </summary>
/// <returns></returns>
[HttpGet("otherget/three")]
[MapToApiVersion("3")]
public IEnumerable<string> Get3()
{
return new string[] { "value1", "value2" };
}
}
<小时>
代码:https://gist.github.com/Alezis/bab8b559d0d8800c994d065db03ab53e
这篇关于如何设置 Swashbuckle 与 Microsoft.AspNetCore.Mvc.Versioning的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!