Это было вызвано отчасти из-за моего неправильного понимания того, как на самом деле вызываются пользовательские ошибки, а также из-за того, что (IMHO) обработка ошибок в asp.net mvc немного запуталась.
Первыйпроблема заключалась в том, что во многих моих методах действий я проверял наличие объекта, например сообщения в блоге, и возвращал HttpNotFoundResult, если сообщение в блоге было пустым.Я предполагал, что тогда будет отображаться пользовательская страница ошибок, которую я установил для ошибок 404.
Однако это не так.Возврат HttpNotFoundResult просто устанавливает код состояния ответа на 404. Остальное затем обрабатывается IIS, отображая страницу ошибок IIS 404 или браузером, если у него есть собственная настраиваемая страница ошибок.
Одно из решений здесьвозвращает HttpException, которое будет использовать ваши пользовательские страницы ошибок, поскольку запрос обрабатывается asp.net.
Вместо этого я решил создать новый ActionResult, который позволил мне указать представлениевместе с кодом статуса http.Я предпочел это выбрасывать исключения.
Следующая проблема заключалась в том, что по умолчанию в новом проекте MVC определен жадный маршрут.Если вы сделаете запрос к /foo/bar
, MvcHandler по умолчанию будет искать контроллер с именем Foo
.Когда он не может найти его, он вернет 404.
Я удалил маршрут по умолчанию и не имел жадных маршрутов.Это означало, что URL-адреса, не соответствующие ни одному из моих маршрутов, не будут обрабатываться asp.net и просто вернутся к IIS.
Решение здесь состояло в том, чтобы создать маршрутный символ в нижней части моей конфигурации маршрутизации для соответствия все других запросов и перенаправление их в пользовательское действие PageNotFound, которое устанавливает код состояния на 404 и отображает мое настраиваемое представление.
Некоторые вещи, на которые стоит обратить внимание.
- Вам нужно будет установить
httpErrors errorMode="Detailed"
для отображения пользовательских страниц ошибок в IIS / IISExpress.Остальные, однако, можно оставить в покое. - Установка пути
defaultRedirect
в разделе customErrors
не влияет на 500 ошибок.Это потому, что глобальный HandleErrorAttribute
обрабатывает все 500 ошибок и просто ищет для отображения представление под названием «Ошибка».Это означает, что если ваша пользовательская страница ошибки фактически является действием контроллера, она не будет вызвана.Вышеприведенное верно даже в том случае, если вы явно указали страницу ошибки 500. - Однако вы все равно должны сохранять путь defaultRedirect, так как он будет использоваться для других кодов состояния, если они не указаны явно.