前提:
需要nuget 以下两个程序集
Swashbuckle.AspNetCore 我暂时用的是 4.01;
Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer 2.2.0
描述:解决 .net core webapi 同一个项目中,多个版本的控制及文档输出;
Controllers 层次如下:
实际效果:(引用他人的git图片)
解决办法:
步骤1 对startup.cs 进行修改代码如下:
1.1 增加私有变量:
/// <summary> /// Api版本提者信息 /// </summary> private IApiVersionDescriptionProvider provider;
1.2 在配置服务 ConfigureServices 中增加如下代码:
services.AddApiVersioning(option =>
{
option.AssumeDefaultVersionWhenUnspecified = true;
option.ReportApiVersions = false;
})
.AddMvcCore().AddVersionedApiExplorer(option =>
{
option.GroupNameFormat = "'v'VVV";
option.AssumeDefaultVersionWhenUnspecified = true;
});
this.provider = services.BuildServiceProvider().GetRequiredService<IApiVersionDescriptionProvider>();
services.AddSwaggerGen(options =>
{
foreach (var description in provider.ApiVersionDescriptions)
{
options.SwaggerDoc(description.GroupName,
new Info()
{
Title = $"接口 v{description.ApiVersion}",
Version = description.ApiVersion.ToString(),
Description = "切换版本请点右上角版本切换"
}
);
}
options.IncludeXmlComments(this.GetType().Assembly.Location.Replace(".dll", ".xml"), true);
});
1.3 在配置http管道 Configure 中增加如下代码:
app.UseSwagger();
app.UseSwaggerUI(c =>
{
foreach (var description in provider.ApiVersionDescriptions)
{
c.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
}
});
步骤2 对Controllers 配置相应版本信息
不同的版本只需改变 [ApiVersion("x.x.x")]
/// <summary>
/// 1.0 版本
/// </summary>
[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version}/[controller]/[action]")]
public class EasenController : ControllerBase
{
..................
}
步骤3 为了更好的在Swagger 文档调试的时候自动填入相应的版本号进行优化
3.1 增加 SwaggerOperationFilter.cs 代码如下:
/// <summary>
/// Swagger 过滤器
/// </summary>
public class SwaggerOperationFilter : IOperationFilter
{
/// <summary>
/// 应用过滤器
/// </summary>
/// <param name="operation"></param>
/// <param name="context"></param>
public void Apply(Operation operation, OperationFilterContext context)
{
#region Swagger版本描述处理
foreach (var parameter in operation.Parameters.OfType<NonBodyParameter>())
{
var description = context.ApiDescription.ParameterDescriptions.First(p => p.Name == parameter.Name);
if (parameter.Description == null)
{
parameter.Description = "填写版本号如:1.0";
parameter.Default = context.ApiDescription.GroupName.Replace("v", "");
}
}
#endregion
}
}
3.2 在 startup.cs ConfigureServices 中对 AddSwaggerGen 配置项进行修改代码如下:
services.AddSwaggerGen(options =>
{
...............
options.OperationFilter<SwaggerOperationFilter>();
});
转自:https://www.cnblogs.com/intotf/p/10075331.html
====================================================================
第一步 导入nuget包
nuget导入Swashbuckle.AspNetCore (对应有Swashbuckle.AspNetCore.Swagger、Swashbuckle.AspNetCore.SwaggerGen、Swashbuckle.AspNetCore.SwaggerUI)
版本控制还需要引入
Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer
Microsoft.AspNetCore.Mvc.Versioning
第二步 添加服务及配置
下面代码中都结合了IdentityServer4中的相关设置,可以忽略
非版本控制
ConfigServices中添加如下代码
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info
{
Version = "v1.0",
Title = "体检微服务接口"
});
var basePath = PlatformServices.Default.Application.ApplicationBasePath;
var xmlPath = Path.Combine(basePath, "ExaminationServicesApi.xml");
options.IncludeXmlComments(xmlPath);
var xmlmodelPath =
Path.Combine(basePath, "ExaminationServicesDomain.xml");
options.IncludeXmlComments(xmlmodelPath);
#region Swagger添加授权验证服务
//options.AddSecurityDefinition("Bearer", new ApiKeyScheme
//{
// Description = "JWT Bearer 授权 \"Authorization: Bearer+空格+token\"",
// Name = "Authorization",
// In = "header",
// Type = "apiKey"
//});
options.AddSecurityDefinition("oauth2", new OAuth2Scheme
{
Type = "oauth2",
Flow = "implicit",
AuthorizationUrl = _authorityconfig.Authority + "/connect/authorize",
Scopes = new Dictionary<string, string>
{
//{ "openid", "身份信息" } ,
//{ "profile", "个人基本信息" } ,
{ "userservicesapi", "用户服务" },
{ "examinationservicesapi", "体检服务" }
}
});
options.OperationFilter<CustomOperationFilter>();
#endregion
});
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApi");
c.OAuthClientId("testuserservicesapiexaminationservicesapi");
c.OAuthAppName("体检服务");
});
这里要注意到我添加了2个xml 一个是apicontroller的获取注释描述,如果需要model相关的描述可以将model所在的应用程序集xml处理下,以便于在接口文档上可以看到model的先关说明
版本控制
ConfigServices中添加如下代码 只不过是动态的处理了版本信息
services.AddApiVersioning(option =>
{
option.AssumeDefaultVersionWhenUnspecified = true;
option.ReportApiVersions = false;
})
.AddMvcCore().AddVersionedApiExplorer(option => {
option.GroupNameFormat = "'v'VVV";
option.AssumeDefaultVersionWhenUnspecified = true;
});
services.AddSwaggerGen(options =>
{
var provider = services.BuildServiceProvider().GetRequiredService<IApiVersionDescriptionProvider>();
foreach (var description in provider.ApiVersionDescriptions)
{
options.SwaggerDoc(description.GroupName,
new Info()
{
Title = $"体检微服务接口 v{description.ApiVersion}",
Version = description.ApiVersion.ToString(),
Description = "切换版本请点右上角版本切换",
Contact = new Contact() { Name = "黎又铭", Email = "[email protected]" }
}
);
}
//options.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info
//{
// Version = "v1.0",
// Title = "体检微服务接口"
//});
var basePath = PlatformServices.Default.Application.ApplicationBasePath;
var xmlPath = Path.Combine(basePath, "ExaminationServicesApi.xml");
options.IncludeXmlComments(xmlPath);
var xmlmodelPath =
Path.Combine(basePath, "ExaminationServicesDomain.xml");
options.IncludeXmlComments(xmlmodelPath);
#region Swagger添加授权验证服务
//options.AddSecurityDefinition("Bearer", new ApiKeyScheme
//{
// Description = "JWT Bearer 授权 \"Authorization: Bearer+空格+token\"",
// Name = "Authorization",
// In = "header",
// Type = "apiKey"
//});
options.AddSecurityDefinition("oauth2", new OAuth2Scheme
{
Type = "oauth2",
Flow = "implicit",
AuthorizationUrl = _authorityconfig.Authority + "/connect/authorize",
Scopes = new Dictionary<string, string>
{
//{ "openid", "身份信息" } ,
//{ "profile", "个人基本信息" } ,
{ "userservicesapi", "用户服务" },
{ "examinationservicesapi", "体检服务" }
}
});
options.OperationFilter<CustomOperationFilter>();
#endregion
});
app.UseSwagger();
app.UseSwaggerUI(c =>
{
foreach (var description in provider.ApiVersionDescriptions)
{
c.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
}
//c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApi");
c.OAuthClientId("testuserservicesapiexaminationservicesapi");
c.OAuthAppName("体检服务");
});
对比两种情况可以看出实际上就多出来一个办理版本信息而已,ApiVersionDescriptions 其实就是通过这个特性动态遍历了版本信息,所以多版本控制只需要在ApiController中添加好相关的属性标签即可
第三步 使用
[ApiVersion("1.0")]
[Route("api/v{api-version:apiVersion}/[controller]")]
public class DemoController : ControllerBase
{
}
在前面代码中我们用到了 CustomOperationFilter这个处理,在这个操作过滤器中我在之前的代码中添加授权及文件上传,这里我们使用版本控制还需要在里面添加好版本参数描述处理
public class CustomOperationFilter : IOperationFilter
{
public void Apply(Operation operation, OperationFilterContext context)
{
#region Swagger版本描述处理
foreach (var parameter in operation.Parameters.OfType<NonBodyParameter>())
{
var description = context.ApiDescription.ParameterDescriptions.First(p => p.Name == parameter.Name);
if (parameter.Description == null)
{
parameter.Description = description.ModelMetadata.Description;
}
}
#endregion
#region Swagger授权过期器处理
if (operation.Security == null)
operation.Security = new List<IDictionary<string, IEnumerable<string>>>();
var oAuthRequirements = new Dictionary<string, IEnumerable<string>>
{
{"oauth2", new List<string> { "openid", "profile", "examinationservicesapi" }}
};
operation.Security.Add(oAuthRequirements);
#endregion
#region Swagger 文件上传处理
var files = context.ApiDescription.ActionDescriptor.Parameters.Where(n => n.ParameterType == typeof(IFormFile)).ToList();
if (files.Count > 0)
{
for (int i = 0; i < files.Count; i++)
{
if (i == 0)
{
operation.Parameters.Clear();
}
operation.Parameters.Add(new NonBodyParameter
{
Name = files[i].Name,
In = "formData",
Description = "Upload File",
Required = true,
Type = "file"
});
}
operation.Consumes.Add("multipart/form-data");
}
#endregion
}
}
运行程序看效果
版本控制就搞定了,这里需要说明的是看下面的图
额外说明
版本是不是必须的、以及描述就是在CustomOperationFilter中处理下默认的说明,你可以这样写
if (parameter.Description == null)
{
parameter.Description ="填写版本号如:1.0";
}
parameter.Required=false; //设置非必填或非必填
下面看下效果,已经有注释了和设置了的非必填项目
这里额外在说一点的就是
[ApiVersion("1.0", Deprecated = false)]
Deprecated 这个属性设置 True :标识是否弃用API ,在设置为true的情况下来看下效果
1.0版本已经是弃用了,这里又要额外说下与这个关联的属性了就是在服务配置选项中的 ReportApiVersions 设置 用下面的配置
services.AddApiVersioning(option =>
{
option.ReportApiVersions = false;
})
.AddMvcCore().AddVersionedApiExplorer(option => {
option.GroupNameFormat = "'v'VVV";
option.AssumeDefaultVersionWhenUnspecified = true;
option.DefaultApiVersion = new ApiVersion(1, 0);
});
false:不再请求响应中添加 版本报告信息,下图中已经不会显示我一用的版本信息了
https://www.cnblogs.com/liyouming/p/9889962.html
上面默认版本 DefaultApiVersion 我设置了1.0 在代码中出现2个版本路由地址一样,在没有填写版本号的情况下使用默认版本
AssumeDefaultVersionWhenUnspecified:true 是否在没有填写版本号的情况下使用默认版本