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
{
    /// 
    /// 登陆图形验证码获取接口
    /// 
    [ApiController]
    [ApiVersion("1.0", Deprecated = false)]
    [Route("ap/v{api-version:apiVersion}/[controller]")]
    [Produces("application/json")]
    public class ImgCodeController : ControllerBase
    {
        /// 
        /// 获取图形验证码
        /// 
        /// 图片宽度
        /// 图片高度
        /// 
        [HttpGet]
        public async Task> 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(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)

 /// 
        /// 
        /// 
        /// 
        /// 
        public static IServiceCollection AddSwagger(IServiceCollection services)
        {
            services.AddTransient, ConfigureSwaggerOptions>();
            services.AddSwaggerGen(c =>
            {
                c.OperationFilter();
                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();
            });
            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
{
    /// 
    /// Configures the Swagger generation options.
    /// 
    /// This allows API versioning to define a Swagger document per API version after the
    ///  service has been resolved from the service container.
    public class ConfigureSwaggerOptions : IConfigureOptions
    {
        readonly IApiVersionDescriptionProvider provider;

        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// The provider used to generate Swagger documents.
        public ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider) => this.provider = provider;

        /// 
        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
    {
        /// 
        /// Applies the filter to the specified operation using the given context.
        /// 
        /// The operation to apply the filter to.
        /// The current operation filter context.
        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.整体效果: