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


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

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

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

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

7 94

7 ответов:

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

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

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

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

установить existingResponse для PassThrough в системе.раздел webServer / httpErrors:

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

значение по умолчанию свойства existingResponse-Auto:

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

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

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

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

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

от сеть.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.асакс:

    Response.TrySkipIisCustomErrors = True

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

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

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

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

в частности, я пытался получить ответ HTTP 404, который перенаправил бы пользователя на нашу пользовательскую страницу 404 (через Интернет.конфиг настроить.)

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

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

тогда мне пришлось настроить и the customErrors и httpError узлы в Интернете.конфиг.

<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 при условии.

The customErrors настройки оказались необходимо для обработки моего явно брошенного HttpException, в то время как httpErrors узел обрабатывал URL-адреса, которые выходили за пределы шаблонов маршрутов, указанных в глобалах.асакс.цезий.

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

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

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

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

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

TrySkipIisCustomErrors это только часть головоломки. Если вы используете пользовательские страницы ошибок, но вы также хотите доставить некоторое спокойное содержимое на основе статусов 4xx, то у вас есть проблема. Настройка веб.конфигурация httpErrors.existingResponse to " Auto "не работает, потому что .net, похоже, всегда доставляет некоторое содержимое страницы в IIS, поэтому использование" Auto " приводит к тому, что все (или, по крайней мере, некоторые) пользовательские страницы ошибок не используются. Использование "заменить" тоже не будет работать, потому что ответ будет содержать ваш код состояния 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 в интернете.конфиг. Теперь:

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

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