如何在保留默认路由时构建仅指向Action和带ID的Controller的路由?
解决ASP.NET路由匹配问题:添加Controller+可选Id的路由
看起来你已经搞定了两种路由,但第二种www.mysite.com/MyController/{OptionalId}的问题主要出在路由顺序和默认Action的设置上。路由匹配是从上到下执行的,所以必须把更具体的路由放在前面,同时要明确指定第二种路由对应的默认Action,否则框架不知道该调用哪个方法。
下面是修正后的完整RouteConfig代码,完美支持你需要的三种路径,同时保留默认路由:
public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); // 第三种路由:直接访问HomeController的指定Action(最具体,优先匹配) routes.MapRoute( name: "HomeActionDirect", url: "MyActionFromHomeController", defaults: new { controller = "Home", action = "MyActionFromHomeController" } ); // 第一种路由:完整的Controller/Action/可选Id(比第二种路由更具体,先匹配) routes.MapRoute( name: "ControllerActionWithOptionalId", url: "{controller}/{action}/{optionalId}", defaults: new { optionalId = UrlParameter.Optional } ); // 第二种路由:访问Controller + 可选Id,默认使用Index Action(可替换为你的默认Action) routes.MapRoute( name: "ControllerWithOptionalId", url: "{controller}/{optionalId}", defaults: new { action = "Index", optionalId = UrlParameter.Optional }, // 可选约束:确保optionalId是数字(避免和Action名称冲突) constraints: new { optionalId = @"\d*" } ); // 默认路由:最后匹配,处理所有未覆盖的情况 routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } }
关键说明:
- 路由顺序是核心:
- 固定URL的第三种路由最具体,必须放在最前面,防止被其他路由拦截。
- 第一种路由(包含Controller+Action)比第二种更具体,所以排在第二种前面,这样
/MyController/MyAction/123会正确匹配到指定的Action,而不会把MyAction当成Id。 - 第二种路由放在第一种之后,确保只有当URL没有指定Action时才会触发。
- 默认Action必须指定:第二种路由里的
action = "Index"告诉框架,当只传入Controller和可选Id时,要调用该Controller的Index方法。如果你的默认Action不是Index,直接替换成对应的名称即可。 - 可选约束防冲突:给
optionalId加上\d*的约束,确保只有数字(或空)会被当成Id。这样如果你的Controller有个Action名称是数字(比如MyController有Action123),/MyController/123会正确匹配到Action123,而不是被当成Id传入Index方法。
验证三种路径:
www.mysite.com/MyController/MyAction/{OptionalId}→ 匹配第一种路由,调用MyController.MyAction(OptionalId)www.mysite.com/MyController/{OptionalId}→ 匹配第二种路由,调用MyController.Index(OptionalId)(或你指定的默认Action)www.mysite.com/MyActionFromHomeController→ 匹配第三种路由,调用HomeController.MyActionFromHomeController()
内容的提问来源于stack exchange,提问作者Vinicius Ottoni
相关产品推荐
相关产品推荐

