我的ASP.NET MVC项目似乎在撰写 URL时忽略了路由默认值。例如,Url.Action("Index", "Home")
返回/Home/Index/
,而它应该只返回/
(我在其他所有MVC网站上都看到过)。 使用网址没有任何问题,例如通过访问http://myserver/
,可以正确找到默认控制器和操作。
我该如何解决这个问题? (请注意,我发现questions询问如何实现这种行为,但似乎没有人会遇到这种相反的问题。)
该项目并不引人注目,没有自定义路由处理程序等,路由配置非常简单:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("LoginHandler");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{*id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
(*
是因为某些操作使用任意字符串作为可能包含嵌入斜杠的标识符,如果没有星号,则路由与此类URL不匹配。)
答案 0 :(得分:2)
问题确实在于小星号。这些catch-all parameters显然与UrlParameter.Optional
默认值不匹配,导致网址始终包含整个路径。
如果要保留默认行为,同时还允许使用catch-all参数语法的任意参数,则需要在辅助路径中使用catch-all参数 :
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("LoginHandler");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "CatchAll",
url: "{controller}/{action}/{*id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
使用此定义,不使用斜杠的简单参数将使用第一个路径处理(如未指定要使用的确切路径时的URL生成),而带有斜杠的复杂参数将回退到第二个路径,并进行处理正确地在那里。
(请注意,这可能只是MVC实现中的一个错误:对于catch-all参数,MVC的ParsedRoute.IsParameterRequired
返回null
作为默认参数值,然后针对提供的{{进行测试1}}来自路由的默认值,并且发现它们是不同的。因此,您可以将路由定义更改为使用UrlParameter.Optional
默认值而不是id = null
,而不是添加辅助路由,它似乎也是工作,但它可能有不必要的副作用,我猜。我也不确定这种行为是故意的,还是只是一个错误。)