如何创建指向RouteConfig中自定义路由AdminGroupsCreateStudent的RouteLink?
我来帮你理清楚这个问题的原因和解决办法:
为什么会跳转到错误的路由?
ASP.NET的路由匹配是按你定义路由的顺序从上到下进行的。你当前的页面URI是admin/groups/1,当你调用RouteLink却没有传递groupId参数时,路由系统会尝试匹配最靠前的符合条件的路由——AdminGroupsEdit的URL模式admin/groups/{id}刚好能匹配这个请求的前缀,所以就错误命中了它,而不是你想要的AdminGroupsCreateStudent。
正确创建RouteLink的方法
你需要显式传递groupId参数给RouteLink,这样路由系统才能准确匹配到AdminGroupsCreateStudent路由。
步骤1:从当前URI获取groupId值
当前页面是通过AdminGroupsEdit路由进来的,对应的路由参数是id(值为1),你可以通过ViewContext.RouteData直接获取这个值:
ViewContext.RouteData.Values["id"]
步骤2:修改RouteLink代码
把获取到的id值作为groupId参数传入routeValues,完整代码如下:
@Html.RouteLink("Add", routeName: "AdminGroupsCreateStudent", routeValues: new { groupId = ViewContext.RouteData.Values["id"] }, htmlAttributes: new { @class = "btn btn-success" })
这样传递参数后,路由系统会找到需要groupId参数的AdminGroupsCreateStudent路由,生成正确的URLadmin/groups/1/students/create-student。
可选优化:调整路由顺序
如果你不想每次都手动传参数,也可以把更具体的路由放在前面定义。因为路由匹配是顺序优先,把AdminGroupsCreateStudent和AdminGroupsEditStudent这类带更多层级的路由放在AdminGroupsEdit前面,就能让更具体的路由优先被匹配:
// 先定义更具体的路由 routes.MapRoute( name: "AdminGroupsCreateStudent", url: "admin/groups/{groupId}/students/create-student", defaults: new { controller = "Student", action = "Create" } ); routes.MapRoute( name: "AdminGroupsEditStudent", url: "admin/groups/{id}/students/{studentid}", defaults: new { controller = "Student", action = "Edit" } ); // 最后定义通用的路由 routes.MapRoute( name: "AdminGroupsEdit", url: "admin/groups/{id}", defaults: new { controller = "Group", action = "Edit" } );
不过这种方式不如显式传参数可靠,因为如果后续路由顺序被调整,可能又会出现匹配错误的问题。
内容的提问来源于stack exchange,提问作者dennismeister

