Как на самом деле работает redirectMode=»ResponseRewrite»?

#asp.net #iis #error-handling #web-config #custom-errors

#asp.net #iis #обработка ошибок #web-config #пользовательские ошибки

Вопрос:

РЕДАКТИРОВАТЬ Итак, мне удалось это исправить, определив Application_Error метод в my Global.asax и вызвать Response.ClearContent оттуда. Не уверен, что это может иметь какие-либо нежелательные побочные эффекты, поэтому все еще интересуюсь ответами на исходный вопрос. /РЕДАКТИРОВАТЬ

Я настроил <customErrors> элемент в своем Web.config с помощью redirectMode="ResponseRewrite" . Согласно MSDN, это должно отображать страницу ошибки без изменения исходного URL.

Это отлично работает, если в одном из событий страницы генерируется исключение, например Page_Load , однако я заметил, что когда вы создаете исключение из встроенного блока кода в вашем .aspx-файле, оно выводит все, что у вас было в вашем .aspx-файле, вплоть до строки, в которой возникает исключение, а затем добавляетсодержимое вашей страницы ошибок соответствует этому, что приводит к полному мусору на стороне клиента.

Возьмите эту простую страницу с Web.config

 <?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.web>
        <customErrors mode="On" defaultRedirect="~/error.aspx" redirectMode="ResponseRewrite" />
    </system.web>
</configuration>
  

и error.aspx страница

 <%@ Page Language="C#" AutoEventWireup="true" %>
<html>
 <head></head>
 <body>
   An error occured
 </body>
</html>
  

и default.aspx это вызывает исключение

 <%@ Page Language="C#" AutoEventWireup="true" %>
<% string s = null; %>
<html>
 <head></head>
 <body>
  <strong>This is a test page.</strong>
  <%= s[0] %>
 </body>
</html>
  

Запрос default.aspx в браузере клиента приведет к подаче следующего искаженного HTML

 <html>
 <head></head>
 <body>
  <strong>This is a test page.</strong>
  
<html>
 <head></head>
 <body>
   An error occured
 </body>
</html>
  

Происходит ли это потому, что на этом этапе HTML-файл default.aspx уже записан в выходной поток? Если да, есть ли способ очистить содержимое выходного потока, чтобы error.aspx клиенту было отправлено только фактическое содержимое? Я попытался вызвать Response.ClearContent() Page_Load моей страницы ошибок, но это не имело никакого эффекта.

Могу ли я что-нибудь сделать, чтобы предотвратить это, кроме как прибегнуть к redirectMode="ResponseRedirect" ? Кроме того, если то, что я написал выше, верно, как redirectMode="ResponseRedirect" это работает в этой ситуации? Если выходной поток уже записан, HTTP-заголовки уже должны быть отправлены, верно?

Комментарии:

1. Вы ничего не можете сделать — такого рода ошибки, которые вы выдаете в середине рендеринга (а не в коде позади), и все готово, чтобы вы отправили какую-то страницу, в первую очередь редки — так зачем беспокоиться о том, чтобы сделать что-то более сложное для обработки ошибки, а не исправить ошибку? Часть страницы полностью готова к рендерингу, только если вы используете ResponseRedirect , вы можете избежать этого типа рендеринга, или если вы используете try / catch и обрабатываете свою ошибку.

2. Это вызвано <%= … %>. <%= … %> эквивалентно ответу. Напишите (…), если в <%= … %> возникает исключение, error.aspx будет записан непосредственно Response . Напишите (…), и содержимое в default.aspx не будет очищено.

3. Встроенные блоки кода поддерживаются в ASP.NET Страницы веб-форм в первую очередь для сохранения обратной совместимости со старой технологией ASP. В общем, использование встроенных блоков кода для сложной логики программирования — не лучшая практика, потому что, когда код смешивается на странице с разметкой, его может быть сложно отлаживать и поддерживать. Поэтому я не рекомендую вам использовать <%= … %> в веб-формах.