IIS7 переопределяет customErrors при установке Response.StatusCode?

Здесь есть странная проблема. Всем известно, что если вы используете раздел web.config customErrors, чтобы создать страницу пользовательской ошибки, вы должны установить свой Response.StatusCode в соответствующее положение. Например, если я создаю пользовательскую 404-страничку и назову ее 404.aspx, я мог бы поместить <% Response.StatusCode = 404 %> в содержимое, чтобы он имел истинный заголовок статуса 404.

Следуй за мной до сих пор? Хорошо. Теперь попробуйте сделать это на IIS7. Я не могу заставить его работать, период. Если на странице пользовательских ошибок установлено значение Response.StatusCode, IIS7 полностью переопределяет страницу пользовательских ошибок и показывает свою собственную страницу состояния (если у вас есть одна настройка).

Кто-нибудь еще видел это поведение и, возможно, знает, как его обойти? Он работал под IIS6, поэтому я не знаю, почему все изменилось.

Примечание. Это не то же самое, что проблема в ASP.NET Custom 404 Возврат 200 OK вместо 404 не найден

Ответ 1

Самый простой способ согласования поведения - очистить ошибку и использовать Response.TrySkipIisCustomErrors и установить значение true. Это переопределит обработку страниц общей ошибки IIS из вашей страницы или глобального обработчика ошибок в Application_Error.

Server.ClearError();
Response.TrySkipIisCustomErrors = true;

Обычно вы должны делать это в своем обработчике Application_Error, который обрабатывает все ошибки, которые обработчики ошибок вашего приложения не захватывают.

Более подробную информацию можно найти в этом блоге: http://www.west-wind.com/weblog/posts/745738.aspx

Ответ 2

Установите существующий запрос ответа на PassThrough в разделе system.webServer/httpErrors:

  <system.webServer>
    <httpErrors existingResponse="PassThrough" />
  </system.webServer>

Значение по умолчанию для существующего свойства Response: Auto:

Авто сообщает настраиваемому модулю ошибок, чтобы сделать право. Фактический текст ошибки, воспринимаемый клиентами, будет зависеть от значения fTrySkipCustomErrors, возвращаемого при вызове IHttpResponse::GetStatus. Если для параметра fTrySkipCustomErrors установлено значение true, пользовательский модуль ошибок позволит пройти ответ, но если он установлен в значение false, модуль пользовательских ошибок заменяет текст собственным текстом.

Дополнительная информация: Что ожидать от пользовательского модуля ошибок IIS7

Ответ 3

Решено: Оказывается, что "подробные ошибки" должны быть включены, чтобы IIS7 мог "перекрыть" любую страницу с ошибкой, которую вы могли бы иметь. См. http://forums.iis.net/t/1146653.aspx

Ответ 4

Я не уверен, что это похоже на природу или нет, но я решил проблему, которая кажется похожей на поверхности, и вот как я ее справился.

Прежде всего, значение по умолчанию для существующегоResponse (Auto) было правильным ответом в моем случае, поскольку у меня есть пользовательские 404, 400 и 500 (я мог бы создать других, но этих трех будет достаточно для того, что я делаю). Вот соответствующие разделы, которые помогли мне.

Из web.config:

<customErrors mode="Off" />

и

<httpErrors errorMode="Custom" existingResponse="Auto" defaultResponseMode="ExecuteURL">
  <clear />
  <error statusCode="404" path="/errors/404.aspx" responseMode="ExecuteURL" />
  <error statusCode="500" path="/errors/500.aspx" responseMode="ExecuteURL" />
  <error statusCode="400" path="/errors/400.aspx" responseMode="ExecuteURL" />
</httpErrors>

Оттуда я добавил это в Application_Error на global.asax:

    Response.TrySkipIisCustomErrors = True

На каждой из моих пользовательских страниц ошибок я должен был включить правильный код статуса ответа. В моем случае я использую пользовательский 404 для отправки пользователей в разные разделы моего сайта, поэтому я не хочу вернуть код статуса 404, если он фактически не является мертвой страницей.

Во всяком случае, как я это сделал. Надежда, которая помогает кому-то.

Ответ 5

Эта проблема была главной головной болью. Ни одно из упомянутых выше предложений не решило его для меня, поэтому я включаю свое решение. Для записи наша среда/платформа использует:

  • .NET Framework 4
  • MVC 3
  • IIS8 (рабочая станция) и IIS7 (веб-сервер)

В частности, я пытался получить ответ HTTP 404, который перенаправляет пользователя на нашу страницу 404 (с помощью настроек Web.config).

Во-первых, мой код должен был выбросить HttpException. Возврат NotFoundResult из контроллера не достиг результатов, которые я получил после.

throw new HttpException(404, "There is no class with that subject");

Затем мне пришлось настроить и узлы customErrors и httpError в Web.config.

<customErrors mode="On" defaultRedirect="/classes/Error.aspx">
  <error statusCode="404" redirect="/classes/404.html" />
</customErrors>

...

<httpErrors errorMode="Custom" existingResponse="Auto" defaultResponseMode="ExecuteURL">
  <clear />
  <error statusCode="404" path="/classes/404.aspx" responseMode="ExecuteURL" />
</httpErrors>

Обратите внимание, что я оставил existingResponse как Auto, который отличается от предложенного решения @sefl.

Настройки customErrors, по-видимому, были необходимы для обработки моего явно загруженного HttpException, а обработанные httpErrors node URL-адреса, которые попадали за пределы шаблонов маршрутов, указанных в Globals.asax.cs.

P.S. С этими настройками мне не нужно было устанавливать Response.TrySkipIisCustomErrors

Ответ 6

По умолчанию IIS 7 использует подробные пользовательские сообщения об ошибках, поэтому я бы предположил, что Response.StatusCode будет равен 404.XX, а не только 404.

Вы можете настроить IIS7 на использование более простых кодов сообщений об ошибках или изменить код обработки более подробных сообщений об ошибках, которые предлагает IIS7.

Дополнительная информация доступна здесь: http://blogs.iis.net/rakkimk/archive/2008/10/03/iis7-enabling-custom-error-pages.aspx

Дальнейшее исследование показало, что у меня это было не так - подробные сообщения не по умолчанию, но, возможно, они были включены, на вашем поле, если вы видите разные сообщения об ошибках, о которых вы упомянули.