Почему я вижу 2 страницы ошибок при выполнении Server.Transfer из Application_Error и errorMode = "Custom"? - PullRequest
3 голосов
/ 18 октября 2010

Мой вопрос тесно связан с этим вопросом .

Вот краткий обзор: мое приложение работает в классическом режиме.У меня есть следующий код в Global.asax

    protected void Application_Error(Object sender, EventArgs e)
    {
        // ... boring stuff...
        HttpContext.Current.Server.Transfer("~/MyErrorPage.aspx", true);
    }

Все работает нормально (т.е. я вижу MyErrorPage.aspx), когда возникает ошибка, если

<httpErrors errorMode="Detailed" />

, но когда errorMode="Custom" (илиerrorMode="DetailedLocalOnly" и запрос от удаленного компьютера), я вижу страницу пользовательской ошибки IIS, за которой следует моя страница ошибки (MyErrorPage.aspx).

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <!-- The contents of the default 500 page as configured in IIS 
         Which for me is the default %SystemDrive%\inetpub\custerr\<LANGUAGE-TAG>\500.htm
    -->
</html> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml" > 
    <!-- The contents of MyErrorPage.aspx -->
</html>

Если я удаляю страницу ошибки 500 по умолчанию изРаздел IIS страницы ошибок, затем я получаю следующий вывод (обратите внимание, что я получаю «Страница не может быть отображена ...» вместо пользовательской страницы 500)

The page cannot be displayed because an internal server error has occurred.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml" > 
    <!-- The contents of MyErrorPage.aspx -->
</html>

Если я шаг через код с помощью отладчиказатем я вижу, что страница IIS 500 сбрасывается на клиента, когда я перехожу через оператор Server.Transfer.
Моя страница с ошибкой затем отправляется в браузер после нормального жизненного цикла страницы MyErrorPage.aspx (как вы бы это сделалиожидать).Я пытался (в отчаянии) очистить содержимое ответа (HttpContext.Current.Response.Clear()) до Server.Transfer, но это не имеет никакого эффекта.Я также пытался позвонить Server.ClearError() до передачи, но это также не имеет никакого эффекта.

Теперь, согласно связанному вопросу, "исправить" - установить errormode="Detailed", но я не хочу видетьподробные страницы ошибок для ошибок, которые не обрабатываются в ASP.Net - например, я бы предпочел видеть пользовательскую страницу 404 IIS вместо подробной страницы, если я введу URL myApp/DoesNotExist.html.[Некоторые из наших клиентов настаивают на том, чтобы пользователи никогда не видели страницу с подробной ошибкой, поскольку она считается потенциальной уязвимостью в безопасности.]

Еще одно «исправление» - вместо этого перенаправить серверную передачу, но я бы предпочелпередача, если это возможно: передача означает, что URL-адрес браузера не изменился. Это означает, что, например, если ошибка произошла из-за того, что app. только запускается, они могут нажать F5, чтобы повторить запрос.Перенаправление явно меняет адрес браузера на страницу ошибки.

У кого-нибудь есть объяснение, почему я вижу это поведение?У кого-нибудь есть решение?

Заранее спасибо.

Редактировать

Я собрал небольшое приложение, которое демонстрирует поведение:

http://rapidshare.com/files/427244682/Err.zip

[Убедитесь, что приложение работает в классическом режиме.]

Если вы нажмете на ссылку, для которой установлены оба аргумента: Transfer и Setstatus, то вы увидите проблему, BANG

Ответы [ 3 ]

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

В Response Response.TrySkipIisCustomErrors есть свойство, которое, по-видимому, не позволяет IIS внедрить собственный код страницы ошибки.Предположительно, вы можете установить значение true, так как ошибка происходит каким-либо образом, поэтому вы не получаете пользовательских страниц ошибок для реальных ошибок, но 404 остаются с IIS.

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

Если ваша пользовательская логика страницы ошибок основана только на номере ошибки, вам следует определить пользовательские страницы ошибок в файле web.config.И установите код состояния на общей странице ошибок на основе кода состояния из Server.GetLastError ().Если вы укажете defaultResponseMode = "ExecuteURL", вы получите URL запрашиваемой страницы в браузере клиента.

<system.web>
<customErrors mode="RemoteOnly" defaultRedirect="~/ErrorPages/CustomErrorPage.aspx" redirectMode="ResponseRewrite">
      <error statusCode="404" redirect="~/ErrorPages/404.aspx"/>
      <error statusCode="500" redirect ="~/ErrorPages/500.aspx"/>
</customErrors>
</system.web>

<system.webServer>
    <httpErrors errorMode="Custom" existingResponse="Replace" defaultPath="~/ErrorPages/CustomErrorPage.aspx" defaultResponseMode="ExecuteURL">
      <error statusCode="404" path="~/ErrorPages/404.aspx"/>
      <error statusCode="500" path ="~/ErrorPages/500.aspx"/>
    </httpErrors>
</system.webServer>

И поместите это в Page_Load

CustomErrorPage * Таким образомвы устранили необходимость в Server.Transfer (это делается неявно enviromnet), и у вас есть общая страница для ошибок, которые не обрабатываются явно.

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

Добавьте следующий атрибут к вашему тегу <httpErrors>:

existingResponse="PassThrough"

и это должно это исправить. PassThrough является значением по умолчанию, когда errorMode="Detailed".

Больше информации на http://blogs.iis.net/ksingla/archive/2008/02/18/what-to-expect-from-iis7-custom-error-module.aspx

...