前面已經介紹過了Swagger的基礎使用了
下面繼續分別詳細說明下 不添加版本控制以及添加版本控制的使用情況,其實也基本一致,對看起來可能更加容易理解
第一步 導入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 = "2939828886@qq.com" } } ); } //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:不再請求響應中添加 版本報告信息,下圖中已經不會顯示我一用的版本信息了
上面默認版本 DefaultApiVersion 我設置了1.0 在代碼中出現2個版本路由地址一樣,在沒有填寫版本號的情況下使用默認版本
AssumeDefaultVersionWhenUnspecified:true 是否在沒有填寫版本號的情況下使用默認版本