ASP.NET MVC两控制器含同名方法导致找不到方法的问题咨询
答案是允许两个控制器拥有同名的Action方法,你遇到的找不到方法的错误,根源在于特性路由的冲突,而非同名方法本身不被允许。
问题原因分析
你在Controller1的SearchBySSN方法上使用了[HttpPost("SearchBySSN")]这个特性路由,它定义了一个全局的路由模板:所有POST请求到/SearchBySSN都会匹配这个方法。当你在Controller2中也给同名方法加上了完全相同的[HttpPost("SearchBySSN")]特性后,ASP.NET的路由系统会出现歧义——它无法判断这个/SearchBySSN的POST请求应该指向哪个控制器的方法,因此返回找不到方法的错误。
解决方案
解决这个冲突有两种常用方式:
1. 给控制器添加路由前缀,让Action路由更具唯一性
在控制器级别添加[Route("[controller]")]特性,这样每个控制器的Action路由都会带上控制器名称作为前缀,避免全局路由冲突:
// Controller1的定义 [Route("[controller]")] public class Controller1 : Controller { [HttpPost("SearchBySSN")] [ValidateAntiForgeryToken] [ClientWebError(IsPartial = true)] public async Task<IActionResult> SearchBySSN(string SSN) { // 你的业务逻辑 } } // Controller2的定义 [Route("[controller]")] public class Controller2 : Controller { [HttpPost("SearchBySSN")] [ValidateAntiForgeryToken] public async Task<IActionResult> SearchBySSN(string SSN) { // 你的业务逻辑 } }
此时,两个Action的路由分别是/Controller1/SearchBySSN和/Controller2/SearchBySSN,你的Ajax调用中@Url.Action("SearchBySSN", "Controller1")会正确生成前者的地址,避免冲突。
2. 放弃全局特性路由,依赖MVC默认路由
如果你不需要自定义全局路由,可以将[HttpPost("SearchBySSN")]改成仅保留[HttpPost],让路由系统使用默认的{controller}/{action}/{id?}模板:
// Controller1的方法修改 [HttpPost] [ValidateAntiForgeryToken] [ClientWebError(IsPartial = true)] public async Task<IActionResult> SearchBySSN(string SSN) { // 你的业务逻辑 } // Controller2的方法修改 [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> SearchBySSN(string SSN) { // 你的业务逻辑 }
这种情况下,路由系统会根据控制器和Action名称的组合来匹配请求,/Controller1/SearchBySSN和/Controller2/SearchBySSN会被正确区分。
内容的提问来源于stack exchange,提问作者Diego

