【问题标题】:Area controllers are being called from root request正在从根请求调用区域控制器
【发布时间】:2012-01-19 06:29:50
【问题描述】:

我的 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 命名空间中。那没有用。区域控制器仍在被调用,请求中没有 areaname。

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

【问题讨论】:

  • 在 MVC4 中“默认”路由声明从 Global.asax 移动到 ~/App_Start/RouteConfig.cs/RegisterRoutes()

标签: asp.net-mvc-3 asp.net-mvc-routing asp.net-mvc-areas


【解决方案1】:

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

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

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

【讨论】:

  • 这也帮助我解决了注册默认路由的问题,我希望它在给定区域中查看视图。 (使用默认路由时未注册区域令牌)。使用 DataTokens 访问器设置“区域”的值就像一个魅力。我见过的许多评论者都认为这是一个错误(即使框架不应该支持这一点)。所以谢谢达林。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-08
  • 2020-07-08
  • 2022-07-17
  • 1970-01-01
  • 1970-01-01
  • 2011-08-20
  • 2018-01-27
相关资源
最近更新 更多