Контроллеры области вызываются из корневого запроса - PullRequest
3 голосов
/ 13 декабря 2011

В моем приложении 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" с действием "Smile".

В файле 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", он вызывает привет контроллер STILL! При этом он ищет представления не в папке myarea / Views, а в папке ~ / Views для «корневого» (необластного) уровня проекта.

Как я могу это исправить, чтобы сервер выдавал исключение 404, этот ресурс не найден, как я и просил несуществующий контроллер?

UPD: Контроллеры в области находятся в пространстве имен:

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

...
}

Контроллеры на уровне «root» находятся в пространстве имен:

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. Это не сработало. Контроллеры областей все еще вызываются с запросом без указания имени.

Может быть, кто-то может объяснить, почему?

1 Ответ

7 голосов
/ 13 декабря 2011

Вы можете установить UseNamespaceFallback=false datatoken при регистрации маршрута по умолчанию в вашем Global.asax, ограничив его поиском только контроллеров в данном пространстве имен.Вы можете взглянуть на следующую запись в блоге .

. Чтобы применить это, добавьте ограничение пространства имен для регистрации в вашем регионе:

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