MVC5中使用RouteAttribute时ActionLink生成错误URL的问题求助
问题原因分析
这个问题的核心在于Edit的POST Action路由没有限定请求方法,且缺少{id}占位符,和GET的Edit路由产生了匹配冲突,而Delete的两个Action因为正确限定了请求方法,所以路由匹配完全正常。
具体细节拆解:
- 你的Delete的GET和POST Action都标注了
[Route("data/links/delete/{id}")],我推测你给POST的Delete加了[HttpPost]特性(否则也会出现同样异常),这就限定了该路由仅响应POST请求。当你用@Html.ActionLink生成GET请求的链接时,路由系统只会匹配GET的Delete路由,自然会把id填充到路由占位符里,生成/data/links/delete/2这种格式。 - 而你的Edit的POST Action只标注了
[Route("data/links/edit")],如果没有加[HttpPost],这个路由会响应所有请求方法(包括GET)。此时路由系统里有两个针对EditAction的路由规则:一个带{id}占位符(GET),一个不带(无请求方法限制)。当你传递id参数生成链接时,路由系统可能优先匹配了不带占位符的规则,导致id只能以查询字符串的形式附加在URL后面,也就是/data/links/edit?id=2。
即使你给Edit的POST加了[HttpPost],但因为它的路由规则里没有{id}占位符,路由系统在匹配时仍可能出现歧义——不过最关键的问题还是POST路由没有限定请求方法。
解决方案
方案1:给Edit的POST Action添加[HttpPost]特性
这是最直接的修复方式,让POST路由仅响应POST请求,彻底避免和GET路由的冲突:
// GET Edit Action [HttpGet] [Route("data/links/edit/{id}")] public ActionResult Edit(int id) { // 你的业务代码 } // POST Edit Action [HttpPost] [Route("data/links/edit")] // 可保留不带{id}的格式,只要限定HttpPost就不会影响GET路由匹配 public ActionResult Edit(LinkModel model) { // 你的业务代码 }
添加[HttpPost]后,生成GET链接时,路由系统只会匹配带{id}的GET路由,就能生成正确的/data/links/edit/2格式URL。
方案2:统一Edit路由的占位符(可选)
如果你希望POST请求也使用带{id}的路由格式,可以把POST的路由也改成带{id},同时加上[HttpPost]:
[HttpPost] [Route("data/links/edit/{id}")] public ActionResult Edit(int id, LinkModel model) { // 你的业务代码 }
这样不管是GET还是POST,路由格式保持一致,能彻底消除匹配歧义。
额外验证:确保路由顺序正确
你的RouteConfig.cs里已经正确先调用了routes.MapMvcAttributeRoutes();,再注册默认路由,这个顺序是完全正确的——属性路由会优先于默认路由匹配,不用调整这里的顺序。
内容的提问来源于stack exchange,提问作者Matthias Burger
相关产品推荐
相关产品推荐

