ASP.NET Core 6 MVC路由参数导致Action无法找到的问题咨询
ASP.NET Core 6 MVC路由冲突与Action调用问题解析
场景与代码示例
开发ASP.NET Core 6 MVC应用时,定义了如下Action方法:
[HttpGet, Route("/Table_Read")] public async Task<JsonResult> Table_Read(string tableName) { }
通过Kendo下拉列表的数据源调用该方法:
@(Html.Kendo().DropDownListFor(m => m.TaskId).HtmlAttributes(new { @class = "form-control" }) .DataValueField("Key") .DataTextField("Value") .DataSource(source => { source.Read(read => { read.Action("Table_Read", "standard").Data("GetSelectedId"); }); }) )
遇到的问题
- 路由设为
/Table_Read时,Action无法被调用,开发者工具显示找不到该方法;将路由改为/Table后可正常调用。 - 移除路由定义也无法正常工作,且当前控制器内无同名Action。
- 最初另一个控制器中相同代码(路由与Action名均为
Table_Read)可正常运行,但后续两个控制器出现冲突,原本正常的控制器也开始抛出HTTP 404错误。 - 修改方法名和路由名后,两个控制器的Action均恢复正常。多次测试发现,当不同控制器的Action同名或路由相同时,加载页面时会报错:
该请求返回HTTP 500错误,未显示控制器名;GET https://localhost:44313/Table_Read?table=1 //error500
该请求返回HTTP 404错误,显示控制器名。GET https://localhost:44313/EAmerica/Table_Read?table=1 // 404
疑问解答
1. 原路由设置为何失效?
你定义的Route("/Table_Read")是绝对路由模板(以/开头),它直接绑定到根路径下的Table_Read,但Kendo下拉列表生成的请求路径是/standard/Table_Read(指定了控制器standard),两者路径不匹配,因此路由系统找不到对应的Action。
2. 为何必须定义路由?
这取决于项目的路由配置:
- 如果Program.cs中仅配置了
app.MapControllers()(仅支持属性路由的Web API模式),未添加传统MVC路由(app.MapControllerRoute),那么MVC控制器的Action必须通过属性路由才能被访问。 - 若未配置传统路由,又不给Action添加路由属性,路由系统无法匹配到目标Action,自然无法访问。
3. 多控制器同名/同路由Action为何冲突?
- 绝对路由冲突:当两个不同控制器的Action都使用
Route("/Table_Read")这类绝对路由时,路由系统无法判断请求应该映射到哪个控制器的Action,触发路由歧义,返回500错误。 - 传统路由下的同名Action问题:如果依赖传统路由,不同控制器存在同名Action时,若请求未指定控制器名(如
/Table_Read),路由系统无法确定目标Action;而指定控制器名后返回404,说明该控制器的Action要么未配置属性路由,要么传统路由未正确生效。
修复建议
- 调整路由属性:如果要通过
控制器/Action路径访问,改用相对路由(去掉开头的/):[HttpGet, Route("Table_Read")] // 或者直接依赖传统路由,仅保留[HttpGet] - 配置传统MVC路由:在Program.cs中添加默认路由配置,让未加属性路由的Action也能被访问:
app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); - 避免路由歧义:不同控制器的Action不要使用相同的绝对路由;若需同名Action,可给路由模板加上控制器前缀:
[HttpGet, Route("[controller]/Table_Read")]
内容的提问来源于stack exchange,提问作者Faisal
相关产品推荐
相关产品推荐

