ASP.NET MVC - перехватывать все маршруты и маршруты по умолчанию - PullRequest
67 голосов
/ 23 октября 2010

Пытаясь заставить мое приложение правильно генерировать 404 ошибки, я реализовал перехват всех маршрутов в конце таблицы маршрутов, как показано ниже:

 routes.MapRoute(
            "NotFound", _
           "{*url}", _
           New With {.controller = "Error", .action = "PageNotFound"} _
       )

Однако, чтобы это работало, мне пришлось удалить маршрут по умолчанию:

{controller}/action/{id}

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

Есть ли более простой способ сделать это, вместо добавления маршрута для каждого контроллера / действия?

Можно ли создать маршрут по умолчанию, который все еще позволяет перехватывать весь маршрут, если пользователь пытается перейти к неизвестному маршруту?

Ответы [ 8 ]

101 голосов
/ 12 января 2011

Использовать ограничения маршрута

В вашем случае вы должны определить маршрут по умолчанию {controller}/{action}/{id} и наложить на него ограничение. Возможно, связано с именами контроллеров или даже действиями. Затем поместите защелку все один за ним, и она должна работать нормально.

Поэтому, когда кто-то запрашивает ресурс, который не соответствует ограничению, маршрут перехвата будет соответствовать запросу.

Итак. Сначала определите маршрут по умолчанию с ограничениями маршрута, а затем перехватите весь маршрут после него:

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    new { controller = "Home|Settings|General|..." } // this is basically a regular expression
);
routes.MapRoute(
    "NotFound",
    "{*url}",
    new { controller = "Error", action = "PageNotFound" }
);
19 голосов
/ 23 октября 2010
//this catches all  requests
routes.MapRoute(
    "Error",
    "{*.}",
     new { controller = "PublicDisplay", action = "Error404" } 
);

добавить этот маршрут в конец таблицы маршрутов

7 голосов
/ 23 октября 2010

Ах, проблема в том, что ваш маршрут по умолчанию перехватывает все 3 сегмента URL .Проблема здесь в том, что маршрутизация выполняется до того, как мы определим, кто будет обрабатывать запрос.Таким образом, любой трехсегментный URL будет соответствовать маршруту по умолчанию, даже если позже он закончится тем, что не будет контроллера для его обработки.

Одна вещь, которую вы можете сделать, - это переопределить метод HandleMissingAction на вашем контроллере.Вы также должны использовать тег, чтобы поймать все 404 проблемы.

2 голосов
/ 23 октября 2010

Ну, я обнаружил, что нет хорошего способа сделать это.Я установил для свойства redirectMode customErrors значение ResponseRewrite.

<customErrors mode="On" defaultRedirect="~/Shared/Error" redirectMode="ResponseRewrite">
    <error statusCode="404" redirect="~/Shared/PageNotFound"/>
</customErrors>

. Это дает мне требуемое поведение, но не отображает отформатированную страницу.

Для меня это плохо сделано, что касается SEO.Тем не менее, я чувствую, что есть решение, которое мне не хватает, так как SO делает именно то, что я хочу достичь.URL остается на странице с ошибкой и выдает 404. Проверьте stackoverflow.com/fail в Firebug.

1 голос
/ 08 февраля 2016

Я бы порекомендовал это как наиболее читаемую версию. Это необходимо в вашем RouteConfig.cs и контроллере ErrorController.cs, содержащем действие PageNotFound. Это может вернуть вид. Создайте PageNotFound.cshtml, и он будет возвращен в ответ на 404:

        routes.MapRoute(
            name:  "PageNotFound",
            url:  "{*url}",
            defaults: new { controller = "Error", action = "PageNotFound" }
        );

Как это прочитать:

name: "PageNotFound"

= создать новый шаблон маршрута с произвольным именем 'PageNotFound'

url:"{*url}"

= использовать этот шаблон для сопоставления всех необработанных маршрутов

defaults: new { controller = "Error", action = "PageNotFound" }

= определить действие, которому будет сопоставлен неправильный путь (метод действия PageNotFound в контроллере ошибок). Это необходимо, поскольку неверно введенный путь, очевидно, не будет сопоставлен ни с каким методом действия

0 голосов
/ 27 декабря 2017

Если вы ищете ASP.NET Core, поймайте все маршруты, и поиск в Google по запросу asp.net core catch all route приведет вас сюда:

Ядро ASP.net MVC перехватывает все статические файлы маршрутизации

0 голосов
/ 02 февраля 2012

Мое решение - 2 шага.

Первоначально я решил эту проблему, добавив эту функцию в мой файл Global.asax.cs:

protected void Application_Error(Object sender, EventArgs e)

Где я пытался привести Server.GetLastError () к HttpException, а затем проверил GetHttpCode. Это решение подробно здесь:

Обработка пользовательских ошибок ASP.NET MVC Application_Error Global.asax?

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

например, эти URL будут отображать страницу 404:

www.site.com / бла

www.site.com / л / ли

однако, www.site.com/blah/blah/blah просто сказал бы, что страница не может быть найдена. Добавление вашего улова на весь маршрут ПОСЛЕ всех моих других маршрутов решено так:

routes.MapRoute(
            "NotFound",
            "{*url}",
            new { controller = "Errors", action = "Http404" }
        );

Однако маршрут NotFound, по-видимому, не направляет запросы с расширениями файлов. Это работает, когда они захвачены разными маршрутами.

0 голосов
/ 23 октября 2010

Возможно, вам лучше настроить документ об ошибке 404 в разделе конфигурации, а затем восстановить маршрут по умолчанию.

FWIW, я думаю, что требование маршрута по умолчанию тоже задерживается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...