You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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同名或路由相同时,加载页面时会报错:
    GET https://localhost:44313/Table_Read?table=1  //error500   
    
    该请求返回HTTP 500错误,未显示控制器名;
    GET https://localhost:44313/EAmerica/Table_Read?table=1    // 404  
    
    该请求返回HTTP 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要么未配置属性路由,要么传统路由未正确生效。

修复建议

  1. 调整路由属性:如果要通过控制器/Action路径访问,改用相对路由(去掉开头的/):
    [HttpGet, Route("Table_Read")]
    // 或者直接依赖传统路由,仅保留[HttpGet]
    
  2. 配置传统MVC路由:在Program.cs中添加默认路由配置,让未加属性路由的Action也能被访问:
    app.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
    
  3. 避免路由歧义:不同控制器的Action不要使用相同的绝对路由;若需同名Action,可给路由模板加上控制器前缀:
    [HttpGet, Route("[controller]/Table_Read")]
    

内容的提问来源于stack exchange,提问作者Faisal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 09:51:06