Как отобразить страницу пользовательских ошибок при выдаче запроса на проверку Исключения?

Мы сконфигурировали наши настраиваемые страницы ошибок, как показано ниже, для исключений, созданных ASP.NET:

<customErrors mode="On" redirectMode="ResponseRewrite">
  <error statusCode="400" redirect="~/400.aspx"/>
  <error statusCode="404" redirect="~/404.aspx"/>
  <error statusCode="500" redirect="~/500.aspx"/>
</customErrors>

Настройка redirectMode="ResponseRewrite" важна, поскольку она гарантирует, что URL-адрес не изменится (я считаю, что ASP.NET выполняет Server.Transfer вместо Response.Redirect).

К сожалению, это не работает для ошибок проверки запроса. Например, если пользовательские ошибки включены, если я перехожу к /some/page/<script>, выполняется проверка запроса ASP.NET, и создается HttpException. Однако вместо отображения моей пользовательской страницы ошибки я получаю следующее сообщение:

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

Ошибка выполнения

Описание: При обработке вашего запроса произошло исключение. Кроме того, при выполнении пользовательских Страница ошибки для первого исключения. Запрос завершен.

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

Кроме того, если я сам поймаю ошибку в Application_Error и выпущу Server.Transfer, она отлично работает, поэтому мне любопытно, что делает ASP.NET под обложками.

Если мы должны справиться с этим самим, есть ли лучшее решение, чем это?

protected void Application_Error(object sender, EventArgs e)
{
    var ex = Server.GetLastError() as HttpException;
    if (ex != null 
        && ex.Message.StartsWith("A potentially dangerous Request.Path value was detected from the client")
        && HttpContext.Current.IsCustomErrorEnabled)
    {
        Server.Transfer("400.aspx");
    }
}

Ответ 1

Чтобы быть уверенным, что вы не опускаете никаких кодов ошибок, которые могут произойти в вашем webapp, вы можете добавить страницу с ошибкой по умолчанию:

<customErrors mode="On" defaultRedirect="Error.aspx" />

И если вы хотите поймать только RequestValidationErrors, чем вы можете обработать его в файле global.asax:

 void Application_Error(object sender, EventArgs e)
 {
    Exception ex = Server.GetLastError();
    if (ex is HttpRequestValidationException)
    {
        Server.ClearError();
        Response.Redirect("RequestValidationError.aspx", false);
    }
 }

Ответ 2

Проблема с использованием параметров customErrors в файле конфигурации заключается в том, что сгенерированное перенаправление может привести к тому, что код статуса HTTP перенаправления (300 series) будет возвращен клиенту/браузеру, когда вы действительно хотите отправить код ошибки HTTP-кода HTTP-кода (500 серий) или код ошибки HTTP клиента (серия 400).

Чтобы проверить код состояния HTTP, возвращаемый вашим сайтом, вы можете использовать Chrome "Дополнительные инструменты > Инструменты разработчика" с выбранной вкладкой "Сеть". Затем вы сможете увидеть код состояния HTTP, возвращаемый вашим веб-сервером, обратно клиенту/браузеру. Если введен неправильный вход в адрес электронной почты, должен быть возвращен статус ошибки клиента (статус HTTP 400), а не код статуса перенаправления (серия 300).

Ошибка "Runtime time", указанная в вашем вопросе, может быть вызвана необработанным условием проверки, которое вызвало ошибку сервера. Такие ошибки требуют дополнительного внимания, но должны возвращать код ошибки сервера (500 серий) в ответе HTTP.

Ошибки веб-сервера обрабатываются на двух уровнях. Один уровень отображается на дисплее содержимого страницы, другой - в возвращаемых кодах состояния HTTP. В идеале они будут соответствовать друг другу.

Ответ 3

 void Application_Error(object sender, EventArgs e) {
    Exception Ex = Server.GetLastError;
    Logger.AddNewLog(Logger.LogType.ErrorLog, sender.ToString, "Error", (Ex.Message 
                    + (Environment.NewLine + Ex.StackTrace)));
    Server.ClearError();
    Response.Redirect("/Error");
}

Ответ 4

Поместите existingResponse="Replace" и subStatusCode="-1" в раздел httpErrors вашего web.config.

Теперь страница отображается как ошибка 400 и отображает страницу с ошибкой.

В вашем приложении
введите описание изображения здесь

В вашем web.config введите описание изображения здесь

Не нужно использовать раздел customErrors

введите описание изображения здесь

* # 8 - это страница, где я генерирую ошибку 500.