ASP MVC 5混合路由下UserController的Create动作出现路由未找到问题
解决ASP MVC5混合路由下的“Route Not Found”问题
看起来你遇到的问题是属性路由和约定路由混合使用时,两个Create动作的路由配置不匹配导致的,咱们一步步拆解问题并解决:
问题根源
你的UserController里存在两个关键配置差异:
HttpGet Create方法没有添加属性路由,所以它遵循约定路由规则,访问路径是/User/Create(对应{controller}/{action}的默认格式)。HttpPost CreateAsync方法加了[Route("Create")],结合控制器的[RoutePrefix("User")],它的属性路由路径是/User/Create,但ASP MVC5有个规则:加了属性路由的方法会脱离约定路由的匹配逻辑,只能通过属性路由访问。
如果表单提交路径和这个属性路由不匹配,或者路由注册顺序错误,就会触发“Route Not Found”错误。
解决方案
方案1:统一使用属性路由(推荐)
给HttpGet Create也加上属性路由,让两个动作共享同一路由路径,通过HTTP方法区分请求类型:
[RoutePrefix("User")] public class UserController : Controller { public UserController() {} [HttpGet] [Route("Create")] // 新增属性路由,和Post方法保持路径一致 public ActionResult Create() { return View(); } [Route("Create")] [HttpPost] public async Task<ActionResult> CreateAsync(UserM m) { if (!ModelState.IsValid) { return View(m); } // 你的业务逻辑代码 return RedirectToAction("Index"); } }
这样两个动作的路由都是/User/Create,Get请求返回视图,Post请求处理提交,完全匹配不会有冲突。
方案2:保留约定路由(适合不想大幅改动的场景)
如果想让HttpGet Create继续使用约定路由,需要完成两个关键设置:
- 调整路由注册顺序
在RouteConfig.cs中,必须先注册属性路由,再注册约定路由,否则属性路由会被覆盖:public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); // 先注册属性路由,这一步必须在约定路由之前 routes.MapMvcAttributeRoutes(); // 再注册默认约定路由 routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } } - 修正表单提交路径
因为CreateAsync方法只能通过属性路由/User/Create访问,所以Create视图中的表单要明确指向这个路径:
或者给Post方法添加路由名称,用路由名生成表单路径:@using (Html.BeginForm("Create", "User", FormMethod.Post)) { <!-- 你的表单控件 --> <input type="submit" value="提交" /> }
视图中对应写法:[Route("Create", Name = "UserCreatePost")] [HttpPost] public async Task<ActionResult> CreateAsync(UserM m) { // ... }@using (Html.BeginRouteForm("UserCreatePost", FormMethod.Post)) { <!-- 表单内容 --> }
额外提醒
- 尽量不要混合使用同一请求场景的路由规则,要么全用属性路由,要么全用约定路由,避免逻辑混淆。
- 检查表单是否正确设置了
FormMethod.Post,不要误写成Get请求。
内容的提问来源于stack exchange,提问作者Ben Donnelly
相关产品推荐
相关产品推荐

