如何防止错误区域的控制器在MVC5中使用

时间:2015-10-30 20:39:27

标签: c# asp.net-mvc asp.net-mvc-5 asp.net-routing

我的MVC应用程序在根/全局级别设置了控制器。这些没有明确的区域。我也有一个“管理”区域。以/ admin /开头的URL将路由到Admin区域中的匹配控制器。其他URL路由到匹配的全局控制器。这在大多数情况下工作正常。

我遇到的问题是,当URL与管理区域中的控制器匹配时,如果全局区域中不存在同名,则请求会错误地路由到管理区域中的控制器。我知道这种情况正在发生,因为我在相关控制器中的匹配操作上设置了一个断点。

例如,我在管理区域中有一个名为CalendarController的控制器。当我访问/admin/calendar时,它会起作用,因为它会在Areas/Admin/Views/Calendar/Index.cshtml中找到操作和相应的视图。访问/calendar时会出现此问题。我在根级别没有名为Calendar的控制器,但由于某种原因,它将请求路由到Admin区域的CalendarController,这是我不想要的。我希望它返回404,因为根级别不存在CalendarController。相反,我得到一个错误,因为它在根级别(/Views/Calendar/Index.cshtml)搜索视图,即使匹配的控制器在管理区域中。

除非网址中包含/ admin,否则如何阻止管理区域搜索匹配的控制器?

这是相关的路线代码,除了名称空间的添加外基本上都是库存。没有命名空间的问题仍然存在。实际应用程序中有更多路由,但我在一个全新的MVC项目中得到了相同的行为。

public class AdminAreaRegistration : AreaRegistration 
{
    public override string AreaName 
    {
        get 
        {
            return "Admin";
        }
    }

    public override void RegisterArea(AreaRegistrationContext context) 
    {
        context.MapRoute(
            "Admin_default",
            "Admin/{controller}/{action}/{id}",
            new { action = "Index", id = UrlParameter.Optional },
            new[] { "AreaProblem.Areas.Admin.Controllers" }
        );
    }
}

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            "Default",
            "{controller}/{action}/{id}",
            new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

Error page

在此屏幕截图中,“根级别”的控制器的含义为Controllers/HomeController。我希望不以/admin开头的网址只查看这些控制器。问题是它在<{1}}中进行 搜索。

Solution explorer

1 个答案:

答案 0 :(得分:4)

因此,MVC路由引擎将查找不同的命名空间以尝试找到匹配的控制器。您可以通过指定命名空间来解决此问题(就像您对管理区域所做的那样)。您还可以使用DataTokens指定路径不搜索其他命名空间。

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    namespaces: new [] { "AreaProblem.Controllers" }
    ).DataTokens["UseNamespaceFallback"] = false;