Настройка страниц ошибок

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core

Последнее обновление: 22.07.2016

С помощью двух секций customErrors и httpErrors в файле конфигурации мы можем задать в ASP.NET MVC 5 обработку статусных кодов ошибок.

Секция customErrors в web.config позволяет задать собственные страницы ошибок для различных статусных кодов HTTP. Правда, применение этой секции имеет ограничения.

Вначале добавим в проект свои страницы ошибок. Например, для обработки ошибки 404 добавим в корень проекта файл 404.html:

<!DOCTYPE html>
<html>
<head>
    <title>Ошибка 404</title>
	<meta charset="utf-8" />
</head>
<body>
    <h2>Ошибка 404. Ресурс не найден</h2>
</body>
</html>

Подобным образом добавим файлы и для других ошибок.

Далее найдем в файле конфигурации web.config секцию system.web и поместим в нее подсекцию customErrors (если эта подсекция уже есть, изменим ее):

<system.web>
   <compilation debug="true" targetFramework="4.6" />
   <httpRuntime targetFramework="4.6" />
   
   <customErrors mode="On">
      <error statusCode="404" redirect="~/404.html"/>
      <error statusCode="403" redirect="~/403.html"/>
   </customErrors>
</system.web>

Внутри секции customErrors помещаются элементы error, каждый из которых задает код ошибки (атрибут statusCode) и страницу переадресации при ошибке (атрибут redirect)

Если мы сейчас запустим приложение и обратимся к несуществующему ресурсу, то нам отобразится наша страница с ошибкой:

customErrors в ASP.NET MVC 5

Однако при такой переадресации мы сталкиваемся с рядом проблем. Во-первых, в качестве адреса используется не оригинальный путь, к которому идет обращение, а 404.html. То есть вместо строки запроса /Home/Some, мы получаем /404.html?aspxerrorpath=/Home/Some. Во-вторых, при отдаче ответа клиент получает статусный код 200, то есть запрос успешно обработан, вместо кода 404.

Чтобы решить первую проблему, добавим к определению секции атрибут redirectMode="ResponseRewrite":

<customErrors mode="On" redirectMode="ResponseRewrite">
    <error statusCode="404" redirect="~/404.html"/>
    <error statusCode="403" redirect="~/403.html"/>
</customErrors>

Теперь страницу с ошибкой можно будет увидеть напрямую по запрошенному пути. Однако клиенту все равно будут отдаваться статусный код 200.

Более того у нас есть еще и другая проблема. Если мы напрямую возвратим из метода контроллера статусный код ошибки, то этот код никак не будет обрабатываться, и настройки в customErrors на него не подействуют. Например:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return HttpNotFound();
    }
}

При обращении к нему мы получим стандартное сообщение об ошибке:

NotFound in ASP.NET MVC 5

И для решения возникших проблем нам надо использовать не customErrors, а элемент httpErrors.

Вначале для обработки ошибок добавим в приложение новый контроллер ErrorController:

public class ErrorController : Controller
{
    public ActionResult NotFound()
    {
        Response.StatusCode = 404;
        return View();
    }

    public ActionResult Forbidden()
    {
        Response.StatusCode = 403;
        return View();
    }
}

Добавим представление для метода NotFound:

@{
    ViewBag.Title = "Ошибка 404";
}

<h2>Ошибка 404. Ресурс не найден</h2>

Подобным образом добавим представление и для других методов.

Далее добавим элемент httpErrors. Этот элемент помещается внутрь секции system.webServer. Если этой секции внутри web.config нет, то ее можно добавить. А узел customErrors мы можем удалить или закомментировать:

<system.web>
   <compilation debug="true" targetFramework="4.6" />
   <httpRuntime targetFramework="4.6" />
    
   <!--<customErrors mode="On"  redirectMode="ResponseRewrite">
    <error statusCode="404" redirect="~/Error/NotFound"/>
    <error statusCode="403" redirect="~/Error/Forbidden"/>
  </customErrors>-->
</system.web>
  
<system.webServer>
  <httpErrors errorMode="Custom" existingResponse="Replace">
    <clear/>
    <error statusCode="404" path="/Error/NotFound" responseMode="ExecuteURL"/>
    <error statusCode="403" path="/Error/Forbidden" responseMode="ExecuteURL"/>
  </httpErrors>
</system.webServer>

Элемент httpErrors имеет ряд настроек. Чтобы протестировать настройки локально, устанавливается атрибут errorMode="Custom". Если тестирование необязательно, и приложение уже развернуто для использования, то можно установить значение errorMode="DetailedLocalOnly".

Значение existingResponse="Replace" позволит отобразить ошибку по оригинальному запрошенному пути без переадресации.

Внутри элемента httpErrors с помощью отдельных элементов error устанавливается обработка ошибок. Атрибут statusCode задает статусный код, атрибут path - адрес url, который будет вызываться, а атрибут responseMode указывает, как будет обрабатываться ответ вызванному url. Атрибут responseMode может принимать три значения:

  • ExecuteURL: производит рендеринг ответа полученного при вызове адреса url из атрибута path

  • Redirect: выполняет переадресацию со статусным кодом 302

  • File: рассматривает адрес url из атрибута path как статическую страницу и использует ее в качестве ответа

Настройки элемента httpErrors могут наследоваться с других уровней, например, от файла конфигурации machine.config. И чтобы удалить все унаследованные настройки, применяется элемент <clear />. Чтобы удалить настройки для отдельных ошибок, применяется элемент <remove />:

<httpErrors errorMode="Custom" existingResponse="Replace">
    <remove statusCode="404"/>
    <remove statusCode="403"/>
    <error statusCode="404" path="/Error/NotFound" responseMode="ExecuteURL"/>
    <error statusCode="403" path="/Error/Forbidden" responseMode="ExecuteURL"/>
</httpErrors>

И теперь, если мы запустим приложение и обратимся по несуществующему пути или к методу, который возвращает статусный код 404, то у нас отобразится ответ от метода NotFound контроллера ErrorController:

Настройка страниц ошибок в ASP.NET MVC 5

Установка атрибута responseMode="File" позволяет использовать в качестве ответа статические файлы. Например, используем ранее определенные файлы ошибок:

<httpErrors errorMode="Custom" existingResponse="Replace">
    <remove statusCode="404"/>
    <remove statusCode="403"/>
    <error statusCode="404" path="404.html" responseMode="File"/>
    <error statusCode="403" path="403.html" responseMode="File"/>
</httpErrors>
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850