ASP.NET MVC Маршруты по умолчанию, доступные через локальные маршруты - PullRequest
9 голосов
/ 06 января 2011

Пока (для краткости) у меня есть один маршрут в global.asax, зарегистрированный так:

routes.Add(new LowercaseRoute("{action}/{id}", new MvcRouteHandler())
  {
    Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = UrlParameter.Optional }),
    DataTokens = rootNamespace
  }); 

Где rootNamespace

var rootNamespace = new RouteValueDictionary(new { namespaces = new[] { "MyApp.Web.Controllers" } });

LowercaseRoute наследуется от Route и просто делает все пути строчными. У меня также есть область, зарегистрированная следующим образом:

context.Routes.Add(new LowercaseRoute("admin/{controller}/{action}/{id}", new MvcRouteHandler())
  {
    Defaults = new RouteValueDictionary(new { action = "List", id = UrlParameter.Optional }),
    DataTokens = adminNamespace
  });

Где adminNamespace - это другое пространство имен, та же идея, что и для маршрута по умолчанию, но с правильным пространством имен. Это отлично работает, я могу получить доступ к URL-адресам, которые выглядят следующим образом:

http://example.com/contact  <- default route, "Home" controller
http://example.com/admin/account  <- area route, "Account" controller, default "List" action

Проблема в том, что это

http://example.com/admin/home/contact

тоже работает. В области «admin» нет «домашнего» контроллера с действием «contact». Он извлекает нужную страницу из "/ contact", но с URL-адресом "/admin/home/contact".

Есть ли способ предотвратить это?

Спасибо.

1 Ответ

17 голосов
/ 06 января 2011

Взгляните на код для AreaRegistrationContext.MapRoute:

public Route MapRoute(string name, string url, object defaults, object constraints, string[] namespaces) {
    if (namespaces == null && Namespaces != null) {
        namespaces = Namespaces.ToArray();
    }

    Route route = Routes.MapRoute(name, url, defaults, constraints, namespaces);
    route.DataTokens["area"] = AreaName;

    // disabling the namespace lookup fallback mechanism keeps this areas from accidentally picking up
    // controllers belonging to other areas
    bool useNamespaceFallback = (namespaces == null || namespaces.Length == 0);
    route.DataTokens["UseNamespaceFallback"] = useNamespaceFallback;

    return route;
}

Обратите особое внимание на маркер UseNamespaceFallback , который по умолчанию имеет значение false.У вас должна быть похожая логика, если вы хотите ограничить поиск пространством имен области.(True = поиск в текущем пространстве имен для контроллера, и при этом поиск не выполняется во всех пространствах имен. False = поиск только в текущем пространстве имен.)

...