.NET Core 3 Web API出现Multiple Routes及npoId参数重复错误
报错触发逻辑
这个异常和你设计的父子资源分层路由结构无关,是被[ApiController]的自动参数推导规则坑了。
你在子级控制器头部已经定义了[Route("api/npos/{npoId}/users")],框架在自动推导方法路由的时候,会把方法参数列表里所有没有显式标注来源的参数,自动拼接成新的路由段加到模板末尾。
对应到你现在的两个方法,框架最终生成的完整路由模板是api/npos/{npoId}/users/{npoId}——同一个npoId在模板里重复出现,直接触发生成路由时的参数名校验,抛出你看到的ArgumentException。
可落地的修复方案
选任意一种适配你业务的写法即可:
- 给参数显式标注来源,告知框架参数的获取位置,不要重复追加到路由模板:
把对应方法的参数加上[FromRoute]标记,明确告诉框架npoId是复用控制器级路由里已存在的参数,不需要额外生成路由段:
(参数里的userId如果是通过路由传递,就换成[HttpPost] public async Task<IActionResult> AddUserToNPO([FromRoute] int npoId, [FromQuery] string userId) [HttpDelete] public async Task<IActionResult> RemoveUserFromNPO([FromRoute] int npoId, [FromQuery] string userId)[FromRoute],和你实际的参数传递逻辑匹配即可) - 显式声明方法级的路由模板,绕开框架的自动拼接逻辑:
只要在Http谓词特性里传入模板字符串(哪怕是空字符串),框架就不会自动把方法参数拼到路由里:[HttpPost("")] // 空字符串表示直接复用控制器级的路由路径 public async Task<IActionResult> AddUserToNPO(int npoId, string userId) [HttpDelete("")] public async Task<IActionResult> RemoveUserFromNPO(int npoId, string userId) - 如果你希望走标准RESTful路径,把userId放到路由层级里,直接把完整的方法路由写全即可:
比如最终路径要实现api/npos/{npoId}/users/{userId},直接在方法的Http谓词特性里写清楚模板:
这种写法下框架会严格按照你声明的模板解析参数,不会出现重复参数问题。[HttpPost("{userId}")] public async Task<IActionResult> AddUserToNPO(int npoId, string userId)
附带的潜在配置问题
你父级控制器里给CreateNPO方法加的[Route("CreateNPO")]特性,会完全覆盖控制器级的api/npos路由前缀,最终生成的方法路径是CreateNPO,而不是你预期的api/npos/CreateNPO。如果需要保留这个路径,要把特性改成[Route("api/npos/CreateNPO")],和控制器的路由规则保持一致。
内容的提问来源于stack exchange,提问作者J.G.Sable
相关产品推荐
相关产品推荐

