Как показывать корректную страницу с ошибкой 404 если не найден action (ASP.NET MVC)? - CodeHelper

Как показывать корректную страницу с ошибкой 404 если не найден action (ASP.NET MVC)?

1

Если в ходе выполнения запроса получил управление некоторый контроллер, но у него не найден подходящий метод (action), то клиенту показывается стандартная страница ошибки 404:

Ошибка сервера в приложении '/'.

Не удалось найти данный ресурс.

Описание: HTTP 404. Возможно, искомый ресурс (или один из зависимых от него компонентов) удален, получил другое имя или временно недоступен. Просмотрите следующий URL-адрес и проверьте, что он введен правильно.

Как переопределить эту страницу (показывать собственную кастомизированную)?

Лучший ответ:

1

Есть два варианта:

1) Настроить роутинг так, чтобы он не пропускал запросы к несуществующим экшенам и добавить к концу таблицы роутинга элемент, перехватывающий все необработанные запросы. Например, следующая настройка роутинга не придусматривает каких-либо ограничений на action:

routes.MapRoute("Default",
    "product/{action}/{id}",
    new
    {
        controller = "Product",
        action = "Index",
        id = ""
    });

Если переписать этот код, дабавив аргумен с ограничениями, то на контроллер ProductController будут перенаправляться не все подряд, а только определенные методы (index и details):

routes.MapRoute("Default",
    "product/{action}/{id}",
    new
    {
        controller = "Product",
        action = "Index",
        id = ""
    },
    new {action = "index|details"});

Тогда запрос на несуществующий action (например, /product/foo) не будет перехвачен этим правилом и поиск подходящего для него контроллера продолжется. Чтобы этот поиск завершился, нужно добавить к таблице роутинга правило, перехватывающее любой необработанный запрос. Так как правила обрабатываются по порядку, то если catch-all-роут добавлен в таблицу последним, то он будет перехватывать все необработанные запросу но не затронет ни одного запроса, относящегося к существующему контроллеру/экшену. Итак, последним правилом добавляем:

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

Это правило перенаправляет все запросы на экшен NotFound контроллера ErrorController. Соответствующий метод может выглядить так:

public class ErrorController : Controller
{
    public ActionResult NotFound()
    {
        controller.Response.StatusCode = 404;             1
        return new ViewResult { ViewName = "Error404" };  2
    }
}

Здесь:

1 — устанавливается статус (404 Not Found);

2 — возвращается вид с кастомизированной страницей 404.

2) Переопределить метод HandleUnknownAction контроллера и выполнить в теле метода необходимые действия — вручную собрать и выполнить ActionResult, возвращающий страницу 404:

protected override void HandleUnknownAction(string actionName)
{
    controller.Response.StatusCode = 404;
    var result = new ViewResult { ViewName = "Error404" };
    result.ExecuteResult(ControllerContext);
}

Новые ответы


0

Можно пойти двумя путями: настроить файл Web.config или дописать некоторое количество кода в свой проект. Подробное описание обоих решений описано по ссылке (не привожу текст здесь, так как он длинный).


v1.7.123.556
© 2009—2010 CodeHelper FAQ | О сайте | Обратная связь | История изменений | Статьи
Creative Commons LicenseМатериалы сайта распространяются под лицензией Creative Commons Attribution-Share Alike 3.0 Unported.