Как я могу создать маршрут, который возвращает URL-адрес без ссылки на контроллер в ASP.NET MVC

У меня есть вызов контроллера DefaultController. Внутри этого контроллера у меня есть представления для того, что было бы эквивалентно статическим страницам.

URL-адреса выглядят так: www.site.com/Default/PageName.

Можно ли создать маршрут, который будет форматировать эти URL-адреса, например:

www.site.com/ИмяСтраницы

Я хочу избежать создания контроллеров для каждого из них. Альтернативой может быть создание страниц .aspx в корне, но могу ли я создать маршруты для этих страниц, т.е.:

www.site.com/PageName.aspx становится www.site.com/PageName ?

Спасибо!


person Rich    schedule 07.02.2010    source источник


Ответы (2)


Вы можете создать явный маршрут для действия PageName на DefaultController следующим образом:

routes.MapRoute(
    "PageName",
    "pagename",
    new { controller = "DefaultController", action = "PageName" }
);

Вы должны поместить этот маршрут перед маршрутом MVC по умолчанию. Самым большим недостатком этого подхода является то, что вам нужно создать один маршрут для каждой статической страницы.

Альтернативным подходом может быть добавление дополнительного маршрута после маршрута MVC по умолчанию:

routes.MapRoute(
    "DefaultController",
    "{page}/{*path}",
    new { controller = "DefaultController", action = "{page}" }
);

Недостатком этого подхода является то, что это правило будет обрабатывать все URL-адреса, даже те, которые обычно возвращают 404.

person Franci Penov    schedule 07.02.2010
comment
большое спасибо! Воспользуюсь первым, на сайте всего несколько страниц. Я предполагаю, что нормальный подход для этих типов страниц - создать обычную страницу aspx в корне? - person Rich; 07.02.2010
comment
Не знаю, каков нормальный подход, я склонен помещать в корень только то, что традиционно ожидают пользовательские агенты (например, robots.txt, favicon.ico и т. д.), а остальное помещать в папку, которая логически их группирует. - person Franci Penov; 08.02.2010

Первый подход

Создайте маршрут, который перехватывает действия:

routes.MapRoute(
    "Catcher1",
    "{action}",
    new { controller = "Default", action = string.Empty });

Но это означает, что вам придется создать столько же действий контроллера на контроллере по умолчанию.

Второй подход

Если вы также хотите избежать этого и вместо этого иметь только один контроллер + действие, напишите маршрут следующим образом:

routes.MapRoute(
    "Catcher2",
    "{path}",
    new { controller = "Default", action = "PageName", path = string.Emtpy },
    new { path = @"[a-zA-Z0-9]+" });

Этот маршрут также определяет ограничение маршрута, поэтому он будет захватывать только те маршруты, которые действительно имеют что-то в первом сегменте маршрута. Вы можете определить это ограничение, чтобы перехватывать только те запросы, которые вам нужны (т.е. path = "Result|Search|Whatever")

тогда ваш DefaultController будет иметь что-то вроде этого:

public ActionResult PageName(string path)
{
    // code goes here
}

Второй подход кажется очень выполнимым, но я бы не рекомендовал его, потому что вся логика должна будет пройти через это действие контроллера (для таких запросов). Было бы лучше разделить эти действия на логические. Те, которые на самом деле делают одно и то же (чтобы у них не было кучи операторов switch или чего-то подобного), должны быть определены с отдельными маршрутами (если их нельзя было сделать с помощью одного).

person Robert Koritnik    schedule 07.02.2010