ASP.NET Core 8.0中Swagger因默认路由动作报冲突错误
解决ASP.NET Core 8.0中Swagger与默认Action路由的冲突问题
问题原因
你配置的控制器路由[ApiController, Route("api/[controller]/{action=Index}")]会让ASP.NET Core生成两个路由模板:
- 无Action参数时:
api/[controller](默认映射到Index方法) - 带Action参数时:
api/[controller]/{action}(映射到指定Action方法)
Swagger生成文档时,会将所有匹配api/[controller]/{action}的GET操作视为同一路径下的重复方法,从而抛出SwaggerGeneratorException冲突错误。
解决方案
方案1:拆分路由配置(推荐)
放弃控制器级的默认Action路由,给每个Action单独配置明确的路由,既能保留GET /api/configuration?key=bookingPref的访问方式,又能避免Swagger冲突:
[ApiController] [Route("api/[controller]")] public class ConfigurationController : ControllerBase { // 匹配 GET /api/configuration?key=bookingPref [HttpGet("")] public IActionResult Index(string key) { // 业务逻辑 return Ok($"获取配置:{key}"); } // 匹配 GET /api/configuration/GetOtherSetting [HttpGet("[action]")] public IActionResult GetOtherSetting() { return Ok("其他配置"); } }
这种方式路由规则清晰,Swagger能准确识别每个Action的路径,不会产生冲突。
方案2:使用Swagger文档过滤器修正路由
如果必须保留控制器级的默认Action路由,可以通过实现IDocumentFilter来修改Swagger生成的文档,移除冲突的路由模板:
1. 实现文档过滤器
public class DefaultActionRouteFixFilter : IDocumentFilter { public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) { var pathsToRemove = new List<string>(); var newPaths = new Dictionary<string, OpenApiPathItem>(); foreach (var (pathKey, pathItem) in swaggerDoc.Paths) { // 识别带默认Action的路由模板 if (pathKey.Contains("{action=Index}")) { // 替换为不带Action参数的路径 var cleanPath = pathKey.Replace("/{action=Index}", ""); newPaths[cleanPath] = pathItem; pathsToRemove.Add(pathKey); } // 移除通用的{action}路由模板(避免与默认路由冲突) else if (pathKey.Contains("{action}") && !pathKey.Contains("=")) { pathsToRemove.Add(pathKey); } } // 移除冲突路径 foreach (var path in pathsToRemove) { swaggerDoc.Paths.Remove(path); } // 添加修正后的路径 foreach (var (path, item) in newPaths) { swaggerDoc.Paths.TryAdd(path, item); } } }
2. 注册过滤器到Swagger
在Program.cs中添加过滤器注册:
builder.Services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" }); // 注册自定义文档过滤器 c.DocumentFilter<DefaultActionRouteFixFilter>(); });
这个过滤器会将Swagger文档中带{action=Index}的路由替换为无Action参数的路径,同时移除通用的{action}路由模板,解决冲突问题。
内容的提问来源于stack exchange,提问作者thran
相关产品推荐
相关产品推荐

