MVC路由选择根目录下的区域控制器



我的控制器在区域内回答非该区域路线上的请求时遇到了困难。所以我有一个这样的设置(额外的东西削减):

/Areas/Security/Controllers/MembersController.cs
/Areas/Security/SecurityAreaRegistration.cs
/Controllers/HomeController.cs

我已经定义了我的安全区域:

namespace MyApp.Web.Areas.Security
{
    public class SecurityAreaRegistration : AreaRegistration
    {
        public override string AreaName
        {
            get
            {
                return "Security";
            }
        }
        public override void RegisterArea(AreaRegistrationContext context)
        {
            context.MapRoute(
                "Security_default",
                "Security/{controller}/{action}/{id}",
                new { action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}

我的全球路由规则:

        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.IgnoreRoute("{*robotstxt}", new { robotstxt = @"(.*/)?robots.txt(/.*)?" });
        routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            namespaces: new string[] { "MyApp.Web.Controllers" }
        );

在我的全局asax中,我做了很多事情,但相关的部分是,我调用AreaRegistration.RegisterAllAreas();,然后调用执行上述操作的路由函数。

但我的问题是,对"/Members/"的请求正在使用我的"默认"路由到达我的Members控制器。。。即使控制器不在我指定的命名空间中。然后,当它试图运行时,它找不到它的视图,因为它们是在区域中定义的,它试图在整个视图文件夹中找到它们。我尝试创建路由名称空间"Weird.Namespace.With.No.Content",但它仍然命中Members控制器——我找不到任何方法让它不使用该控制器。我如何使它不回答不在其范围内的请求?

最终通过将Route更改为:找到了解决方案

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

由于某种原因,无论控制器在哪里,它似乎总是能找到它们,并完全忽略我的命名空间——甚至是来自其他引用的程序集。查看DefaultControllerFactory的ILSpy,如果GetControllerType在您要求的名称空间中找不到控制器,它看起来最终会返回到搜索所有控制器。。。

这个标志似乎是在我在特定地区制作的路线上自动设置的,但不是在我在全球制作的路线。当我把它放在全球范围内时,他们开始按照我最初的预期行事。我不知道你为什么要打开这个…

您也应该在您的区域上注册命名空间。

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

然后确保所有的控制器都在它们适当的名称空间中。

您在注册主路线后是否调用了register所有区域?

这是MVC模板的默认片段(注意区域注册是如何首先进行的)

AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);

最新更新