.Net 6 Web Api配置Swagger版本控制不生效问题求解
.NET 6 Web API 版本控制+Swagger配置异常修复方案
核心配置错误点
- 重复注册
AddApiVersioning服务:先后两次调用API版本控制注册方法,两次配置的AssumeDefaultVersionWhenUnspecified、ApiVersionReader参数不一致,导致版本识别逻辑冲突。 - 缺失必要依赖包:未安装
Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer包,该包负责向Swagger提供API版本分组的元数据,原生Swashbuckle无法自动感知版本配置。 - Swagger配置不全:仅在UI层硬编码了两个版本的文档端点,未在文档生成阶段配置按版本拆分逻辑,运行时不会生成多版本的swagger.json文件,切换版本自然加载失败。
- 中间件顺序错误:Swagger相关中间件被放在
MapControllers之后注册,不符合.NET中间件管道执行顺序,导致Swagger路由无法正常匹配。 - 控制器重名冲突:两个版本的同名
MessageController未划分独立命名空间,会直接触发编译错误。
修复步骤
1. 安装缺失NuGet包
确保项目安装以下三个包,且Microsoft.AspNetCore.Mvc.Versioning和Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer版本保持一致(推荐5.1.0版本适配.NET 6):
Swashbuckle.AspNetCoreMicrosoft.AspNetCore.Mvc.VersioningMicrosoft.AspNetCore.Mvc.Versioning.ApiExplorer
2. 替换Program.cs全部配置
删除原有重复的ConfigureServices方法和冗余配置,替换为以下代码:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ApiExplorer; using Microsoft.AspNetCore.Mvc.Versioning; var builder = WebApplication.CreateBuilder(args); // 基础服务注册 builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); // 仅保留一次API版本控制配置 builder.Services.AddApiVersioning(options => { options.DefaultApiVersion = new ApiVersion(1, 0); options.AssumeDefaultVersionWhenUnspecified = true; options.ReportApiVersions = true; options.ApiVersionReader = new UrlSegmentApiVersionReader(); }); // 注册版本API探索器,为Swagger提供版本元数据 builder.Services.AddVersionedApiExplorer(options => { options.GroupNameFormat = "'v'VVV"; options.SubstituteApiVersionInUrl = true; }); // 配置Swagger按版本生成文档 builder.Services.AddSwaggerGen(options => { var apiVersionProvider = builder.Services.BuildServiceProvider() .GetRequiredService<IApiVersionDescriptionProvider>(); foreach (var apiVersionDesc in apiVersionProvider.ApiVersionDescriptions) { options.SwaggerDoc(apiVersionDesc.GroupName, new() { Title = $"业务接口文档 {apiVersionDesc.ApiVersion}", Version = apiVersionDesc.ApiVersion.ToString() }); } }); var app = builder.Build(); // 开发环境加载Swagger中间件,注意顺序要在MapControllers之前 if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(options => { var apiVersionProvider = app.Services.GetRequiredService<IApiVersionDescriptionProvider>(); foreach (var apiVersionDesc in apiVersionProvider.ApiVersionDescriptions) { options.SwaggerEndpoint( $"/swagger/{apiVersionDesc.GroupName}/swagger.json", apiVersionDesc.GroupName.ToUpper()); } }); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
3. 按版本划分控制器命名空间
不要在同一命名空间下定义同名控制器,按版本建立目录结构:
- 目录
Controllers/V1下存放1.0版本控制器,命名空间为你的项目名.Controllers.V1 - 目录
Controllers/V2下存放2.0版本控制器,命名空间为你的项目名.Controllers.V2
控制器路由模板统一使用版本占位符,无需硬编码版本号:
v1版本控制器示例:
using Microsoft.AspNetCore.Mvc; namespace YourProjectName.Controllers.V1 { [ApiVersion("1.0")] [Route("api/v{version:apiVersion}/[controller]")] [ApiController] public class MessageController : ControllerBase { [HttpGet] public IActionResult Get() => Ok("V1版本消息接口返回"); } }
v2版本控制器示例:
using Microsoft.AspNetCore.Mvc; namespace YourProjectName.Controllers.V2 { [ApiVersion("2.0")] [Route("api/v{version:apiVersion}/[controller]")] [ApiController] public class MessageController : ControllerBase { [HttpGet] public IActionResult Get() => Ok("V2版本消息接口返回"); } }
提示:路由模板中的
{version:apiVersion}约束会自动校验请求路径中的版本号是否合法,配合SubstituteApiVersionInUrl配置,Swagger文档会自动生成对应版本的请求路径,无需手动维护。
内容的提问来源于stack exchange,提问作者JsonStatham
相关产品推荐
相关产品推荐

