如何修改Swagger UI端点路由中的Swagger Server路径以简化显示?
问题分析与解决方案
你遇到的核心问题是:既要保留控制器原有路由(保证实际请求能正确匹配),又要让Swagger UI显示简化后的端点路径。之前两种方案的问题根源如下:
- 方案1:仅设置
Servers但未修改Swagger文档中的原始路径,导致Swagger将Server URL与原始路径拼接,出现重复前缀(如/api/public/api/public/v1.0/Test)。 - 方案2:修改控制器路由后,Swagger显示路径正确,但实际路由缺少
/api/public或/api前缀,无法匹配控制器,因此返回404。
正确解决思路
需要同时修改Swagger文档中的路径(去掉前缀)和配置正确的Server URL:
- 保留控制器原有路由(确保实际请求能被正确路由)。
- 通过文档过滤器移除Swagger文档中路径的
/api/public或/api前缀,让UI显示简化路径。 - 配置
Servers的URL为对应的前缀,使Swagger在发送测试请求时,自动将Server URL与简化路径拼接成正确的请求地址。
具体实现代码
1. 创建文档过滤器(移除路径前缀)
public class RemoveApiPrefixFilter : IDocumentFilter { // 需要移除的前缀列表 private readonly string[] _prefixes = { "/api/public", "/api" }; public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) { var pathsToRemove = new List<string>(); var newPaths = new Dictionary<string, OpenApiPathItem>(); foreach (var (originalPath, pathItem) in swaggerDoc.Paths) { foreach (var prefix in _prefixes) { if (originalPath.StartsWith(prefix)) { // 生成去掉前缀的新路径 var simplifiedPath = originalPath.Substring(prefix.Length); pathsToRemove.Add(originalPath); newPaths.Add(simplifiedPath, pathItem); break; } } } // 移除原始路径,添加简化后的路径 foreach (var path in pathsToRemove) { swaggerDoc.Paths.Remove(path); } foreach (var (path, item) in newPaths) { swaggerDoc.Paths.Add(path, item); } } }
2. 配置Swagger服务与中间件
// 注册Swagger服务 services.AddSwaggerGen(c => { // 注册API版本文档(根据你的版本配置调整) c.SwaggerDoc("v1", new OpenApiInfo { Title = "API 文档", Version = "v1.0" }); // 添加文档过滤器 c.DocumentFilter<RemoveApiPrefixFilter>(); }); // 启用Swagger中间件 app.UseSwagger(c => { c.PreSerializeFilters.Add((swaggerDoc, httpReq) => { // 配置Server列表,对应两种前缀 swaggerDoc.Servers = new List<OpenApiServer> { new OpenApiServer { Url = "/api/public", Description = "公开API" }, new OpenApiServer { Url = "/api", Description = "内部API" } }; }); }); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "API v1.0"); });
进阶:拆分公开/内部API文档
如果需要将公开和内部API分开显示,可以通过文档分组实现:
services.AddSwaggerGen(c => { c.SwaggerDoc("public-v1", new OpenApiInfo { Title = "公开API", Version = "v1.0" }); c.SwaggerDoc("internal-v1", new OpenApiInfo { Title = "内部API", Version = "v1.0" }); c.DocumentFilter<RemoveApiPrefixFilter>(); // 筛选不同分组的API c.DocInclusionPredicate((docName, apiDesc) => { if (docName == "public-v1") { return apiDesc.RelativePath.StartsWith("api/public"); } else if (docName == "internal-v1") { return apiDesc.RelativePath.StartsWith("api") && !apiDesc.RelativePath.StartsWith("api/public"); } return false; }); }); // Swagger UI配置 app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/public-v1/swagger.json", "公开API v1.0"); c.SwaggerEndpoint("/swagger/internal-v1/swagger.json", "内部API v1.0"); });
这样配置后,Swagger UI会显示简化后的/v1.0/Test路径,测试请求时会自动拼接Server URL,生成正确的/api/public/v1.0/Test或/api/v1.0/Internal地址,同时控制器原有路由保持不变,不会出现404问题。
内容的提问来源于stack exchange,提问作者pkExec
相关产品推荐
相关产品推荐

