要解决的问题:目前网上大多数是多文件的版本控制(比如:Test1Controller.cs Test2Controller.cs)。这种方法,有诸多缺点,尤其是对于小的改动。
我们的方法:在一个文件中,写多个不同的函数,实现多版本控制。
基本原理:
第一步: 设计版本的枚举变量(V1、V2、V3等等),主要是方便以后修改
namespace WebApplication1.BaseInfor { /// <summary> /// Api版本枚举类 /// </summary> public enum ApiVersions { /// <summary> /// 版本V1 /// </summary> V1 = 1, /// <summary> /// 版本V2 /// </summary> V2 = 2 } }
第二步:告诉编译器,产生API文档
第三步:修改Program.cs文件,告诉他 “要生成那些文档”,“要利用那些文档”
using Microsoft.AspNetCore.Mvc; using Microsoft.OpenApi.Models; using Newtonsoft.Json; using System.Reflection; using WebApplication1.BaseInfor; var builder = WebApplication.CreateBuilder(args); // Add services to the container. //AddNewtonsoftJson 用于输入输出格式化 builder.Services.AddControllers().AddNewtonsoftJson(options => { //忽略循环引用,否则处理嵌套json容易出错 options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; }); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(options => { // 注释 var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; // 第二个参数为是否显示控制器注释,我们选择true options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename), true); // 生成多个文档显示 typeof(ApiVersions).GetEnumNames().ToList().ForEach(version => { //添加文档介绍 options.SwaggerDoc(version, new OpenApiInfo { Title = $"项目名", Version = version, Description = $"项目名:{version}版本" }); }); }); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(options => { //options.SwaggerEndpoint($"/swagger/V1/swagger.json", $"版本选择:V1"); //如果只有一个版本也要和上方保持一致 typeof(ApiVersions).GetEnumNames().ToList().ForEach(version => { //切换版本操作 //参数一是使用的哪个json文件,参数二就是个名字 options.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"版本选择:{version}"); }); }); } app.UseAuthorization(); app.MapControllers(); app.Run();
第四步:在Controller文件中,写多个版本
using Microsoft.AspNetCore.Mvc; using System.Diagnostics; using System.Linq.Expressions; using WebApplication1.BaseInfor; namespace WebApplication1.Controllers { [ApiController] [Route("api/[controller]/[action]")] [Produces("application/json")] public class TestController : ControllerBase { /// <summary> /// 获取授权的token /// </summary> /// <param name="loginHelper"></param> /// <returns></returns> [HttpPost("/Test/" + nameof(ApiVersions.V1) + "/Login")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ApiExplorerSettings(GroupName = nameof(ApiVersions.V1))] //下面这个语法在netcore6.0已经无效了 //[ApiVersion("V1",Deprecated =true)] public IActionResult Login_V1(LoginHelper loginHelper) { //return new UnauthorizedResult(); return Ok(new { code = 200, message = "登录成功", token = "w4905284otijswo;irejgfowu7849p85tu32w4ptojsgoihvl;iusgrowi98ruhikuvs", loginHelper }); } [HttpPost("/Test/" + nameof(ApiVersions.V2) + "/Login")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ApiExplorerSettings(GroupName = nameof(ApiVersions.V2))] public IActionResult Login_V2(LoginHelper loginHelper) { //return new UnauthorizedResult(); return Ok(new { code = 200, message = "登录成功", token = "w4905284otijswo;irejgfowu7849p85tu32w4ptojsgoihvl;iusgrowi98ruhikuvs", loginHelper }); } /// <summary> /// 如果不标识版本,那么这个函数出现在任何一个版本中 /// </summary> /// <param name="loginHelper"></param> /// <returns></returns> [HttpPost] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] public IActionResult Logout(LoginHelper loginHelper) { //return new UnauthorizedResult(); return Ok(new { code = 200, message = "登录成功", token = "w4905284otijswo;irejgfowu7849p85tu32w4ptojsgoihvl;iusgrowi98ruhikuvs", loginHelper }); } } public record LoginHelper(string UserName, string PassWord); }