IIS7 переопределяет customErrors при установке Response.StatusCode? - PullRequest
97 голосов
/ 12 января 2009

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

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

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

Примечание: это не то же самое, что проблема в ASP.NET Custom 404, возвращающий 200 OK вместо 404, не найденный

Ответы [ 7 ]

115 голосов
/ 01 апреля 2009

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

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

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

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

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

80 голосов
/ 02 мая 2009

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

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

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

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

11 голосов
/ 12 января 2009

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

4 голосов
/ 31 июля 2013

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

Прежде всего, значение по умолчанию для существующего ответа (Авто) было правильным ответом в моем случае, так как у меня есть пользовательские 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, если это не мертвая страница.

В любом случае, вот как я это сделал. Надеюсь, это кому-нибудь поможет.

3 голосов
/ 26 февраля 2014

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

  • .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 обрабатывал URL-адреса, которые выходили за пределы шаблонов маршрутов, указанных в Globals.asax.cs.

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

0 голосов
/ 28 декабря 2017

TrySkipIisCustomErrors - это только часть головоломки. Если вы используете пользовательские страницы ошибок, но также хотите доставить некоторый контент RESTful, основанный на статусах 4xx, у вас возникла проблема. Задание для http.rfig.existingResponse web.config значения «Авто» не работает, потому что .net, кажется, всегда доставляет часть содержимого страницы в IIS, поэтому использование «Авто» приводит к тому, что все (или, по крайней мере, некоторые) страницы пользовательских ошибок не используются. Использование «Заменить» также не сработает, поскольку ответ будет содержать ваш код состояния http, но его содержимое будет пустым или заполнено пользовательской страницей ошибок. А «PassThrough» фактически отключает CEP, поэтому его нельзя использовать.

Так что если вы хотите обойти CEP для некоторых случаев (под обходом я имею в виду возвращение статуса 4xx с некоторым содержимым), вам потребуется дополнительный шаг: очистить ошибку:

void Application_Error(object sender, EventArgs e)
{
    var httpException = Context.Server.GetLastError() as HttpException;
    var statusCode = httpException != null ? httpException.GetHttpCode() : (int)HttpStatusCode.InternalServerError;

    Context.Server.ClearError();
    Context.Response.StatusCode = statusCode;
}

Поэтому, если вы хотите использовать ответ REST (т.е. 400 - неверный запрос) и отправить с ним некоторый контент, вам просто нужно установить TrySkipIisCustomErrors где-нибудь в действии и установить existingResponse на «Авто» в разделе httpErrors в web.config. Сейчас:

  • когда нет ошибки (действие возвращает 4xx или 5xx) и возвращается некоторое содержимое, CEP не используется и содержимое передается клиенту;
  • при возникновении ошибки (возникает исключение) содержимое, возвращаемое обработчиками ошибок, удаляется, поэтому используется CEP.

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

0 голосов
/ 12 января 2009

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...