区域控制器正在从根请求调用

发布于 2024-12-21 02:23:31 字数 2338 浏览 0 评论 0原文

我的 ASP.NET MVC3 应用程序中有一些区域:

namespace MyProject.Areas.myarea
{
    public class myareaAreaRegistration : AreaRegistration
    {
        public override string AreaName
        {
            get
            {
                return "myarea";
            }
        }

        public override void RegisterArea(AreaRegistrationContext context)
        {
            context.MapRoute(
                "myarea_default",
                "myarea/{controller}/{action}/{id}",
                new { action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}

该区域包含带有“微笑”操作的“Hello”控制器。

在整个项目的 global.asax 文件中,我有:

    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 }
        );

    }

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
    }

因此,当我请求“localhost/myarea/hello/smile”时,它会按预期调用适当的控制器。

但!当我请求“localhost/hello/smile”时,它仍然调用 hello 控制器!这样,它不在 myarea/Views 文件夹中查找视图,而是在 ~/Views 文件夹中查找项目的“根”(非区域)级别。

我该如何解决这个问题,这样服务器就会抛出 404 异常,找不到该资源,就像我请求不存在的控制器一样?

UPD: 区域中的控制器位于命名空间中:

namespace MyProject.Areas.myarea.Controllers
{
    public class HelloController : Controller

...
}

“根”级别的控制器位于命名空间中:

namespace MyProject.Controllers
{
    public class AnotherRootController : Controller
...
}

所以我在 global.asax 中尝试了此操作:

    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 [] { "MyProject.Controllers" } //Namespace
        );

    }

我认为这会将此路由限制为“根”级别控制器只是,因为它们位于 MyProject.Controllers 命名空间中。那没有用。区域控制器仍在通过请求进行调用,但其中不包含区域名称。

也许有人可以解释一下,为什么?

I have some area in my ASP.NET MVC3 Application:

namespace MyProject.Areas.myarea
{
    public class myareaAreaRegistration : AreaRegistration
    {
        public override string AreaName
        {
            get
            {
                return "myarea";
            }
        }

        public override void RegisterArea(AreaRegistrationContext context)
        {
            context.MapRoute(
                "myarea_default",
                "myarea/{controller}/{action}/{id}",
                new { action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}

this area contains "Hello" controller with "Smile" action.

In global.asax file for whole project I have:

    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 }
        );

    }

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
    }

So, when I request "localhost/myarea/hello/smile" it calls appropriate controller as expected.

BUT! When I request "localhost/hello/smile" it calls hello controller STILL! With that, it looks for the Views not in the myarea/Views folder, but in a ~/Views folder for "root" (non-area) level of project.

How can I fix this, so server will throw an 404 exception, that resource is not found, just like I requested non-existing controller?

UPD: Controllers in area are in namespace:

namespace MyProject.Areas.myarea.Controllers
{
    public class HelloController : Controller

...
}

Controllers in "root"-level are in namespace:

namespace MyProject.Controllers
{
    public class AnotherRootController : Controller
...
}

So I tried this in global.asax:

    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 [] { "MyProject.Controllers" } //Namespace
        );

    }

I thought this would restrict this route to "root"-level controllers only, since they are in MyProject.Controllers namespace. That DID NOT work. Area-controllers are still being called with request without areaname in it.

May be someone can explain, why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

疯到世界奔溃 2024-12-28 02:23:31

在 Global.asax 中注册默认路由时,您可以设置 UseNamespaceFallback=false 数据令牌,方法是将其限制为仅查找给定命名空间中的控制器。您可以查看以下博客文章

因此,要将其付诸实践,请在您的区域注册中添加命名空间限制:

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

并在注册默认路由时在 Global.asax 中将 UseNamespaceFallback 数据令牌设置为 false,以便将其限制到给定的命名空间:

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[] { "MyProject.Controllers" }
    ).DataTokens["UseNamespaceFallback"] = false;
}

You could set the UseNamespaceFallback=false datatoken when registering the default route in your Global.asax by restricting it to look only for controllers in the given namespace. You may take a look at the following blog post.

So to put that into action add a namespace restriction to your area registration:

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

and in your Global.asax set the UseNamespaceFallback data token to false when registering the default route in order to constrain it to the given namespace:

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[] { "MyProject.Controllers" }
    ).DataTokens["UseNamespaceFallback"] = false;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文