ASP.NET Core MVC中asp-route标签生成链接异常,为何与控制器方法名相关而非仅依赖路由配置?
我来给你解释这个现象背后的原因,其实是ASP.NET Core MVC标签辅助器的工作逻辑导致的:
先看你遇到的两个场景:
场景1:方法名与路由动作名不一致
你在HomeController.cs里写了这段代码:
[HttpGet] [Route("[controller]/PravaPristupa/{firstId:int}/{secondId:int}")] public IActionResult Test() { return View(); }
视图里用的是:
<a asp-action="PravaPristupa" asp-route-firstId="33" asp-route-secondId="44">Test link</a>
这时候生成的链接是Home/PravaPristupa?firstId=33&secondId=44——参数变成了查询字符串,不符合你的预期。
场景2:方法名与路由动作名一致
把方法名改成PravaPristupa后:
[HttpGet] [Route("[controller]/PravaPristupa/{firstId:int}/{secondId:int}")] public IActionResult PravaPristupa() { return View(); }
生成的链接就变成了Home/PravaPristupa/33/44,完全符合路由模板的结构。
为什么会这样?
核心原因是:asp-action标签辅助器是通过「方法名称」来匹配路由的,而不是直接匹配路由模板里的路径段。
在场景1里,你用asp-action="PravaPristupa",标签辅助器会去HomeController里找名为PravaPristupa的方法,但你的方法实际叫Test,根本找不到对应的方法。这时候它无法关联到你给Test方法加的自定义路由模板,只能退而求其次使用默认路由规则,把参数作为查询字符串附加到URL后面。
而场景2里,方法名和asp-action指定的名称一致,标签辅助器找到了对应的方法,同时识别到该方法上绑定的Route属性模板,自然就按照模板的结构把参数嵌入到URL路径中。
解决方案:方法名与路由动作名分离的处理
如果你想保持方法名和路由里的动作名称不一样,有两个靠谱的办法:
给方法加
[ActionName]别名:
在Test方法上加上别名属性,让标签辅助器能找到它:[HttpGet] [ActionName("PravaPristupa")] [Route("[controller]/PravaPristupa/{firstId:int}/{secondId:int}")] public IActionResult Test() { return View(); }这样视图里的
asp-action="PravaPristupa"就能正确匹配到Test方法,同时使用自定义路由模板生成链接。使用命名路由生成链接:
给你的路由规则起一个名字,直接通过路由名来匹配,完全不依赖方法名:[HttpGet] [Route("[controller]/PravaPristupa/{firstId:int}/{secondId:int}", Name = "PravaPristupaRoute")] public IActionResult Test() { return View(); }视图里改成用路由名来生成链接:
<a asp-route="PravaPristupaRoute" asp-route-firstId="33" asp-route-secondId="44">Test link</a>
这样就能彻底摆脱方法名对链接生成的限制,完全按照你定义的路由规则来生成URL了。
备注:内容来源于stack exchange,提问作者Marko

