要解決的問題:目前網上大多數是多文件的版本控制(比如: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); }