ASP.NET MVC3 Площадь контроллера доступна из глобальных маршрутов? - PullRequest
5 голосов
/ 16 октября 2011

Возможно, я не правильно понимаю, как работают области MVC, но это немного смутило меня.

  1. Добавление области с именем «MyArea» с помощью щелчка правой кнопкой мыши «Добавить область» в Visual Studio в проекте MVC3
  2. Создание контроллера для MyArea: «AnArea» с соответствующим представлением в области MyArea.
  3. Добавить "controller =" AnArea "в context.MapRoute параметр по умолчанию в методе MyAreaAreaRegistration.RegisterArea.

Так что в этот момент, если вы запустите приложение и перейдете к / MyArea /, он должен загрузить контроллер AnArea с соответствующим ему представлением. Если вы перейдете к / MyArea / AnArea, он покажет тот же результат.

Но, если вы перейдете к / AnArea /, контроллер все равно будет найден и появится следующее сообщение об ошибке:

The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/anarea/Index.aspx
~/Views/anarea/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/anarea/Index.cshtml
~/Views/anarea/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml

Это правильное поведение? Я бы подумал, что к контроллеру области можно получить доступ только через его собственную область, а не глобально.

Ответы [ 3 ]

6 голосов
/ 16 октября 2011

Каждый раз, когда я создаю проект с областями, я изменяю свой маршрут Default следующим образом:

    routes.MapRoute( 
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // defaults
        null,  // constraints
        new string[] { "MyApplication.Controllers" } // namespaces
    );

Последний параметр ограничивает маршрут по умолчанию для контроллеров в пространстве имен MyApplication.Controllers. Это гарантирует, что маршрут по умолчанию ограничен действиями за пределами любых областей.

UPDATE

После глубокого погружения в код я обнаружил, где возникает проблема, и нашел решение. Измените маршрут по умолчанию на следующий:

routes.Add(
    "Default", 
    new Route("{controller}/{action}/{id}",
        new RouteValueDictionary(
            new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        ),
        null,
        new RouteValueDictionary(
            new {
                Namespaces = new string[] { "MyApplication.Controllers" },
                UseNamespaceFallback = false 
            }
        ),
        new MvcRouteHandler()
    )
);

Ключ в добавлении токена UseNamespaceFallback. Это предотвратит просмотр маршрута по умолчанию в любых других пространствах имен.

Это неожиданное поведение, и это была проблема, о которой я не знал, которая влияет на проект, над которым я работаю. Я перечислю это как проблему в aspnet.codeplex.com. Я бы не назвал это ошибкой, но поведение определенно нарушает правила маршрутизации MVC.

0 голосов
/ 16 октября 2011

Вы, кажется, переходите к /AnArea, тогда как ваша область называется MyArea, поэтому вам следует перейти к /MyArea/. Вот как выглядит регистрация маршрута:

context.MapRoute(
    "MyArea_default",
    "MyArea/{controller}/{action}/{id}",
    new { controller = "AnArea", action = "Index", id = UrlParameter.Optional }
);

AnArea - это имя контроллера, а не области. Если вы хотите перейти к какому-либо контроллеру этой области, вы всегда должны добавлять префикс к вашему URL-адресу MyArea, который является названием области.

0 голосов
/ 16 октября 2011

Вы должны применить ограничение пространства имен как к области, так и к общему маршруту.

В global.asax.cs вы должны отредактировать метод RegisterRoutes так же, как этот

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

Это будет ограничивать "// "только к пространству имен" MyProject.Controllers "

Но также вам придется применить ограничение пространства имен к области, чтобы ограничить" // "только к пространству имен" MyProject.Areas.MyArea.Controllers«

Для этого вам нужно отредактировать метод« RegisterArea »для« MyAreaAreaRegistration.cs », как показано ниже (« MyAreaRegistration.cs »находится в папке« / MyProject / Areas / MyArea »):

//Some default code stuff
...
public override void RegisterArea(AreaRegistrationContext context)
{
   context.MapRoute(
      "MyArea_default",
      "MyArea/{controller}/{action}/{id}",
      new { action = "Index", id = UrlParameter.Optional },
      new string[] { "MyProject.Areas.MyArea.Controllers" }
   );
}

Надеюсь, это поможет !!

...