MVC 路由匹配无效的路由

MVC route matching routes that aren't valid

问题

对于默认路由,MVC 返回 "Multiple types were found that match the controller named 'admin'." 错误而不是 404 未找到。该名称空间中没有管理控制器。

我们正在使用 MVC 5.2.2。

背景

我们正在使用 MVC 区域。两个区域包含一个 "admin" 控制器。当您使用各自路由中定义的完整路径时,两个区域的管理控制器都可以访问并正常工作。

当您尝试从默认路由访问 "admin" 时出现问题。管理员在该上下文中不存在,因此我们期望找不到 404,但是我们收到:

 Multiple types were found that match the controller named 'admin'. This can happen 
 if the route that services this request ('{controller}/{action}/{id}') does not 
 specify namespaces to search for a controller that matches the request. If this 
 is the case, register this route by calling an overload of the 'MapRoute' method 
 that takes a 'namespaces' parameter.

  The request for 'admin' has found the following matching controllers:
  DMP.Stock.Web.Controllers.AdminController
  DMP.Inventory.Web.Controllers.AdminController 

这是我们的默认路线和两条区域路线:

 public static void RegisterRoutes(RouteCollection routes)
 {
   // Default Route
   routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    namespaces: new string[] { "DMP.Core.Web.Controllers" }
    );
 }

 public override void RegisterArea(AreaRegistrationContext context)
 {
   // Area 1: Stock
   context.MapRoute(
    name: "Stock_default",
    url: "Stock/{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    namespaces: new string[] { "DMP.Stock.Web.Controllers" }
     );
 }

 public override void RegisterArea(AreaRegistrationContext context)
 {
  // Area 2: Inventory 
  context.MapRoute(
   "Inventory_default",
   "Inventory/{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    namespaces: new string[] { "DMP.Inventory.Web.Controllers" }
     );
 }

/Stock/Admin/Index 工作正常。

/Inventory/Admin/Index 正常工作。

/Admin/ 无法正常工作(预期:找不到 404,收到 "multiple controllers" 错误)。

错误提示我们向路由添加命名空间,但正如您在上面看到的,默认区域和两个区域都已经有命名空间定义。默认路由指向其中没有任何 "admin" 控制器的命名空间。

我认为 MVC 正试图通过搜索可以匹配请求 URL 的可能控制器来成为 "helpful"。有什么办法可以关闭它吗?

我已经能够自己解决这个问题。这是我找到的解决方案:

 // Default Route
 routes.MapRoute(
   name: "Default",
   url: "{controller}/{action}/{id}",
   defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, 
   namespaces: new string[] { "DMP.Core.Web.Controllers" }
        ).DataTokens["UseNamespaceFallback"] = false;

注意添加.DataTokens["UseNamespaceFallback"] = false;这就是解决问题的方法。没有太多(任何?)关于此功能的文档,但是我在阅读 MVC 源代码时发现了它,特别是在 DefaultControllerfactory 中(本期的来源)。

在您了解 google 后 "UseNamespaceFallback" 您可以找到一些博客文章和问题,其中人们遇到了类似的问题并以相同的方式解决了它。但是我找不到关于此 DataToken 的 MSDN 文档。