我有这个配置
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "TestRoute",
url: "home/MyTestDrillDown/{productcat}",
defaults: new { controller = "Home", action = "MyTestDrillDown" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
我想将TestRoute配置为
routes.MapRoute(
name: "TestRoute",
url: "home/MyTestDrillDown/{productcat}"
);
但我看到以下错误。 匹配的路线不包含“控制器”路线值,这是必需的。
我的理解是,如果我有一个硬编码的网址,那么它直接匹配一个控制器和一个动作,在我的情况下"home/MyTestDrillDown/{productcat}"
匹配 HomeController 和 MyTestDrillDown < / em>行动。
我确信我遗漏了一些非常基本和重要的内容,因为存在MapRoute
方法的重载,该方法仅将 Name 和 Url 作为参数。
由于
答案 0 :(得分:6)
MVC管道需要controller
和action
路由值。如果您将路线定义为:
routes.MapRoute(
name: "TestRoute",
url: "home/MyTestDrillDown/{productcat}"
);
当网址与此路由匹配时,路由系统将提取单个路由值productcat
参数。将不会提取controller
和action
路由值。这就是你需要定义这样一条路线的原因:
routes.MapRoute(
name: "TestRoute",
url: "home/MyTestDrillDown/{productcat}",
defaults: new { controller = "Home", action = "MyTestDrillDown" }
);
这样,当网址与此路由匹配时,将提取controller
和action
路由值(即使它们被定义为默认值而不是从实际网址中提取)
您需要记住,路由系统独立于MVC,并且在运行MVC特定代码之前,先在ASP.Net pipeline中发生。
当您致电routes.MapRoute()
时,您只是呼叫extension method,它会在路由表中添加Route
个实例。您在ASP.Net中添加的每条路线都需要IRouteHandler
,而IHttpHandler
会返回MapRoute
。所有路由系统都会找到与当前URL匹配的第一条路由并提取路由数据值。然后路由处理程序将启动处理该路由匹配的请求的特定代码的组件。 (参见msdn上的routing)。
对于MVC,使用MvcHandler
扩展名会添加MvcRouteHandler
,而MvcHandler
会返回RouteData.GetRequiredString
。 ProcessRequestInit
是启动MVC特定管道的那个。例如,查看源代码中的controller
,您将看到需要名为string controllerName = RequestContext.RouteData.GetRequiredString("controller");
的路由值,用于创建控制器实例:
{{1}}
如果路由提取的参数中没有具有此类名称的路由值,则{{3}}会引发异常。 (这是您在问题中注意到的例外情况)