asp.net core 3.1 WebApi 版本管理,以及Swagger JWT Authorization的使用配置
1.WebApi 版本管理使用示例:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using AP.Portal.Application.Contracts.Dtos; using AP.Portal.WebApi.Models; using AP.Portal.WebApi.Unitily; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; namespace AP.Portal.WebApi.Controllers { /// <summary> /// 登陆图形验证码获取接口 /// </summary> [ApiController] [ApiVersion("1.0", Deprecated = false)] [Route("ap/v{api-version:apiVersion}/[controller]")] [Produces("application/json")] public class ImgCodeController : ControllerBase { /// <summary> /// 获取图形验证码 /// </summary> /// <param name="width">图片宽度</param> /// <param name="height">图片高度</param> /// <returns></returns> [HttpGet] public async Task<Result<ImgCodeModel>> Get(int width=200,int height=60) { var imgCode = VerifyCodeHelper.CreateVerifyCode(width,height); var id= Guid.NewGuid().ToString("N"); await RedisHelper.SetAsync(id,imgCode.ImgCodeString,180); return await Task.FromResult(new Result<ImgCodeModel>(imgCode.ErrorCode,imgCode.ErrorMessage,new ImgCodeModel { ImgCodeBase64=imgCode.ImgCodeBase64,ImgCodeUId=id}) ); } } }
2.所需类库:
3.版本控制配置代码示例:
services.AddApiVersioning(options => { options.ReportApiVersions = true; }); services.AddVersionedApiExplorer(//services-->IServiceCollection options => { // add the versioned api explorer, which also adds IApiVersionDescriptionProvider service // note: the specified format code will format the version as "'v'major[.minor][-status]" options.GroupNameFormat = "'v'VV";//v1.0 //如果是v1.0.0--"'v'VVV" // note: this option is only necessary when versioning by url segment. the SubstitutionFormat // can also be used to control the format of the API version in route templates options.SubstituteApiVersionInUrl = true; });
4.Swagger的配置示例:(此处Swagger 配置的是Jwt验证方案,也就是请求头添加Authorization Bearer xxx)
/// <summary> /// /// </summary> /// <param name="services"></param> /// <returns></returns> public static IServiceCollection AddSwagger(IServiceCollection services) { services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>(); services.AddSwaggerGen(c => { c.OperationFilter<SwaggerDefaultValues>(); c.SwaggerDoc("AP-Portal", new OpenApiInfo { Title = "AP-Portal Api", Version = "v1" }); c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Description = "请输入Token,格式为Bearer XXX", Name = "Authorization", In = ParameterLocation.Header, Type = SecuritySchemeType.ApiKey,// BearerFormat = "JWT", Scheme = "Bearer" }); //Json Token认证方式,此方式为全局添加 c.AddSecurityRequirement(new OpenApiSecurityRequirement() { { new OpenApiSecurityScheme{ Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }, new string[] { } } }); var baseDirectory = System.AppDomain.CurrentDomain.BaseDirectory; var xmlFile = System.AppDomain.CurrentDomain.FriendlyName + ".xml"; var xmlPath = Path.Combine(baseDirectory, xmlFile); c.IncludeXmlComments(xmlPath); //var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; //var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); //c.IncludeXmlComments(xmlPath); //c.OperationFilter<AuthTokenHeaderFilter>(); }); return services; }
public void Configure(IApplicationBuilder app, IApiVersionDescriptionProvider provider, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseSwagger(); app.UseSwaggerUI(options => { // build a swagger endpoint for each discovered API version foreach (var description in provider.ApiVersionDescriptions) { options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant()); } }); app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
using Microsoft.AspNetCore.Mvc.ApiExplorer; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace AP.Portal.WebApi { /// <summary> /// Configures the Swagger generation options. /// </summary> /// <remarks>This allows API versioning to define a Swagger document per API version after the /// <see cref="IApiVersionDescriptionProvider"/> service has been resolved from the service container.</remarks> public class ConfigureSwaggerOptions : IConfigureOptions<SwaggerGenOptions> { readonly IApiVersionDescriptionProvider provider; /// <summary> /// Initializes a new instance of the <see cref="ConfigureSwaggerOptions"/> class. /// </summary> /// <param name="provider">The <see cref="IApiVersionDescriptionProvider">provider</see> used to generate Swagger documents.</param> public ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider) => this.provider = provider; /// <inheritdoc /> public void Configure(SwaggerGenOptions options) { // add a swagger document for each discovered API version // note: you might choose to skip or document deprecated API versions differently foreach (var description in provider.ApiVersionDescriptions) { options.SwaggerDoc(description.GroupName, CreateInfoForApiVersion(description)); } } static OpenApiInfo CreateInfoForApiVersion(ApiVersionDescription description) { var info = new OpenApiInfo() { Title = "API", Version = description.ApiVersion.ToString(), Description = "A sample application with Swagger, Swashbuckle, and API versioning.", Contact = new OpenApiContact() { Name = "Bill Mei", Email = "bill.mei@somewhere.com" }, License = new OpenApiLicense() { Name = "MIT", Url = new Uri("https://opensource.org/licenses/MIT") } }; if (description.IsDeprecated) { info.Description += " This API version has been deprecated."; } return info; } } }
using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.ApiExplorer; namespace AP.Portal.WebApi { public class SwaggerDefaultValues : IOperationFilter { /// <summary> /// Applies the filter to the specified operation using the given context. /// </summary> /// <param name="operation">The operation to apply the filter to.</param> /// <param name="context">The current operation filter context.</param> public void Apply(OpenApiOperation operation, OperationFilterContext context) { var apiDescription = context.ApiDescription; operation.Deprecated |= apiDescription.IsDeprecated(); if (operation.Parameters == null) { return; } // REF: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/412 // REF: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/pull/413 foreach (var parameter in operation.Parameters) { var description = apiDescription.ParameterDescriptions.First(p => p.Name == parameter.Name); if (parameter.Description == null) { parameter.Description = description.ModelMetadata?.Description; } if (parameter.Schema.Default == null && description.DefaultValue != null) { parameter.Schema.Default = new OpenApiString(description.DefaultValue.ToString()); } parameter.Required |= description.IsRequired; } } } }
5.版本管理Swagger配置微软官网示例下载:https://github.com/microsoft/aspnet-api-versioning
6.注意事项:webApi 接口必须是Restful风格否则显示会有问题,(add :HttpPost ,edit:HttpPut,delete:HttpDelete,Query:HttpGet),必须明确标注不然无法正常显示
7.swagger 请求头 Authorization在页面的最上边一次性配置,不用每个接口都配置:
7.如何使用Swagger为.NET Core 3.0应用添加JWT授权说明文档
8.整体效果: