代码之家  ›  专栏  ›  技术社区  ›  Bryan

当没有指定区域时,ASP.NET MVC 2 RC 2返回区域特定的控制器

  •  5
  • Bryan  · 技术社区  · 16 年前

    我有一个基本的mvc2(RC2)站点和一个基本层控制器(“Home”),还有一个区域(“Admin”)和一个控制器(“Abstract”)。当我打电话的时候 http://website/Abstract -管理区域中的抽象控制器被调用,即使我没有在URL中指定区域。更糟糕的是,它似乎不知道它在Admin下,因为它找不到关联的视图,只返回:

    The view 'Index' or its master was not found. The following locations were searched:
    ~/Views/Abstract/Index.aspx
    ~/Views/Abstract/Index.ascx
    ~/Views/Shared/Index.aspx
    ~/Views/Shared/Index.ascx
    

    2 回复  |  直到 16 年前
        1
  •  12
  •   Brad B.    16 年前

    在“Admin”区域的“AdminAreaRegistration.cs”类中,可能有类似于以下内容的内容:

    // Web/Areas/Admin/AdminAreaRegistration.cs
    
    public override void RegisterArea(AreaRegistrationContext context) {
        context.MapRoute(
            "Admin_default",
            "Admin/{controller}/{action}/{id}",
            new { action = "Index", id = UrlParameter.Optional }
        );
    }
    

    因此,当你要求 http://website/Abstract

    // Web/Global.asax.cs
    
    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}
        );
    }
    

    “Default”路由成功匹配 http://website/Abstract ,其中“controller”=“Abstract”、“action”=“Index”(默认值)和“id”=urlparmeter.Optional(默认值)。这是正确的,也是有意的行为。。。目前为止

    现在,MVC框架将尝试加载“抽象”控制器。根据设计,MVC将搜索一个名为“AbstractController”的类,该类将“Controller”扩展到web项目的文件/命名空间层次结构中的任何位置。需要注意的是,控制器的文件位置和名称空间不会影响MVC查找它的能力;换句话说,仅仅因为您将“AbstractController”放在一个名为“Areas\Admin\Controllers”的文件夹中,并将名称空间改为“Web.Areas.Admin.Controllers”而不是“Web.Controllers”,并不意味着MVC不会使用它。

    The view 'Index' or its master was not found. The following locations were searched:
    ~/Views/Abstract/Index.aspx
    ~/Views/Abstract/Index.ascx
    ~/Views/Shared/Index.aspx
    ~/Views/Shared/Index.ascx
    

    我们,就像你一样,不想被要求 http://website/Abstract http://website/Admin/Abstract “应该有用。我想不出为什么会有人想要这种行为。

    一个简单的解决方案是删除Global.asax中的“Default”路由, 但是 这将破坏任何常规的非区域控制器/视图。这可能不是大多数人的选择。。。

    因此,我们认为可以限制MVC将用于与Global.asax中的“Default”路由匹配的请求的控制器集:

    // Web/Global.asax.cs
    
    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},
            new[] {"Web.Controllers"} // Added this line
        );
    }
    

    http://website/Abstract 仍然

    -热释光;答案从这里开始-

    // Web/Global.asax.cs
    
    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},
            new[] {"Web.Controllers"}
        ).DataTokens["UseNamespaceFallback"] = false; // Added this line
    }
    

    将“Default”路由上DataTokens字典的“UseNamespaceFallback”键设置为false。现在,当我们要求 ,仍将匹配“默认”路由(这是有效行为!)但MVC会的 使用不在已定义命名空间内的任何控制器;在这种情况下,只有“Web.Controllers”命名空间中的控制器才有效。最后,这是我们要找的功能!我们不明白为什么这不是默认行为。奇怪吧?

    希望这有帮助。

    推荐文章