Сервер не может установить состояние после отправки заголовков HTTP IIS7.5 - PullRequest
69 голосов
/ 05 марта 2010

Иногда в производственной среде я получаю исключение:

  • Информация о процессе
    • Идентификатор процесса: 3832
    • Имя процесса: w3wp.exe
    • Имя учетной записи: NT AUTHORITY \ NETWORK SERVICE
  • Информация об исключении
    • Тип исключения: System.Web.HttpException
    • Сообщение об исключении: Сервер не может установить состояние после отправки заголовков HTTP.
  • Запрос информации
    • URL запроса: http://www.myulr.pl/logon
    • Путь запроса: / logon
    • Адрес хоста пользователя: 10.11.9.1
    • Пользователь: user001
    • Аутентифицировано: True
    • Тип аутентификации: Формы
    • Имя учетной записи потока: NT AUTHORITY \ NETWORK SERVICE
  • Информация о теме
    • ID темы: 10
    • Имя учетной записи потока: NT AUTHORITY \ NETWORK SERVICE
    • Выдает себя за: Ложь
Stack trace: at System.Web.HttpResponse.set_StatusCode(Int32 value) at  
System.Web.HttpResponseWrapper.set_StatusCode(Int32 value) at  
System.Web.Mvc.HandleErrorAttribute.OnException(ExceptionContext filterContext) at  
System.Web.Mvc.ControllerActionInvoker.InvokeExceptionFilters(ControllerContext controllerContext, IList(1) filters, Exception exception) at  
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) at System.Web.Mvc.Controller.ExecuteCore() at  
System.Web.Mvc.MvcHandler.<>c__DisplayClass8.<BeginProcessRequest>b__4() at  
System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0() at  
System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8(1).<BeginSynchronous>b__7(IAsyncResult _) at  
System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult(1).End() at   
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) at  
System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at  
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& ompletedSynchronously) 

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

Я использую ASP.NET MVC 2 (Release Candidate 2)

Ответы [ 10 ]

59 голосов
/ 23 мая 2010

Я согласен с Вагрантом о причине:

  1. ваше действие выполнялось, запись разметки в поток ответов
  2. поток был небуферизован, что заставило заголовки ответа записываться до того, как могла начаться запись разметки.
  3. В вашем представлении обнаружена ошибка во время выполнения
  4. Обработчик исключений срабатывает при попытке установить код состояния на что-то другое, кроме 200
  5. Сбой, потому что заголовки уже отправлены.

Если я не согласен с Vagrant, это средство «не вызывать ошибок в привязке» - вы все равно можете столкнуться с ошибками во время выполнения в привязке View, например, исключение нулевой ссылки.

Лучшее решение для этого - убедиться, что Response.BufferOutput = true; перед отправкой байтов в поток ответа. например в вашем действии контроллера или On_Begin_Request в приложении. Это позволяет устанавливать передачу сервера, файлы cookie / заголовки и т. Д. Вплоть до естественного завершения ответа или завершения вызова / сброса.

Конечно, также проверьте, что буфер не сбрасывается / не устанавливается в ложь и далее в стеке.

MSDN HttpResponse.BufferOutput

45 голосов
/ 27 октября 2010

Просто чтобы добавить к ответам выше. У меня была такая же проблема, когда я впервые начал использовать ASP.Net MVC, и я делал Response.Redirect во время действия контроллера:

Response.Redirect("/blah", true);

Вместо того, чтобы возвращать действие Response.Redirect, я должен был возвращать RedirectAction:

return Redirect("/blah");
15 голосов
/ 19 мая 2010

HTTP-сервер не отправляет заголовок ответа обратно клиенту, пока вы не укажете ошибку или не начнете отправлять данные. Если вы начнете отправлять данные обратно клиенту, то сервер должен сначала отправить заголовок ответа (который содержит код состояния). После того, как заголовок отправлен, вы больше не можете помещать код статуса в заголовок, очевидно.

Вот обычная проблема. Вы запускаете страницу и отправляете несколько начальных тегов (т. Е. <head>). Затем сервер отправляет эти теги клиенту после первой отправки заголовка ответа HTTP с предполагаемым состоянием SUCCESS. Теперь вы начинаете работать над содержанием страницы и обнаруживаете проблему. Вы не можете отправить сообщение об ошибке, поскольку заголовок ответа, который будет содержать состояние ошибки, уже отправлен.

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

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

11 голосов
/ 07 мая 2014

У меня была такая же проблема с настройкой StatusCode и затем Response.End в HandleUnauthorizedRequest методе AuthorizeAttribute

var ctx = filterContext.HttpContext;
ctx.Response.StatusCode = (int)HttpStatusCode.Forbidden;
ctx.Response.End();

Если вы используете .NET 4.5+, добавьте эту строку перед Response.StatusCode

filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;

Если вы используете .NET 4.0, попробуйте SuppressFormsAuthenticationRedirectModule .

10 голосов
/ 18 января 2012

Как насчет проверки этого перед выполнением перенаправления:

if (!Response.IsRequestBeingRedirected)
{
   //do the redirect
}
3 голосов
/ 26 апреля 2011

Вы на самом деле пытаетесь перенаправить страницу, на которую есть какой-то ответ. Поэтому сначала вы сохраняете информацию, которую вы выбросили, в буфер, используя response.buffer = true в начале страницы, а затем очищаете ее, когда требуется, используя response.flush, эта ошибка будет исправлена ​​

1 голос
/ 20 сентября 2018

Мы получили ту же ошибку - так что это может быть полезно для некоторых.

Для нас причина была очень простой. Изменение интерфейса сбило с толку конечного пользователя, и он нажимал кнопку возврата в браузере в «плохое» время после отправки формы (конечно, мы должны были использовать шаблон PRG, но мы этого не сделали).

Мы исправили проблему, и пользователь больше не нажимает кнопку возврата. Проблема решена.

1 голос
/ 27 октября 2016

Я извиняюсь, но я добавляю свои 2 цента в ветку на тот случай, если у кого-то возникнет такая же проблема.

  • Я использовал проверку подлинности с помощью форм в своем приложении MVC
  • Нонекоторые действия контроллера были «анонимными», то есть разрешенными для неаутентифицированных пользователей
  • Иногда в этих действиях я бы все же хотел бы, чтобы пользователи перенаправлялись в форму входа при некоторых условиях
  • чтобы сделать это - у меня есть это в моем методе действия: return new HttpStatusCodeResult(401) - и ASP.NET очень приятно это обнаружить, и он перенаправляет пользователя на страницу входа!Волшебство, верно?У него даже есть правильный ReturnUrl параметр и т. Д.

Но вы видите, куда я попал?Я возвращаю 401 .И ASP.NET перенаправляет пользователя.Что по сути возвращает 302 .Один код состояния заменяется другим.

И некоторые серверы IIS (только некоторые!) Выдают это исключение.Некоторые нет.- У меня его нет на моем тестовом serevr, только на моем производственном сервере (не всегда так правильно o_O)

Я знаю, что мой ответ по сути повторяет то, что здесь уже сказано, но иногда это простоТрудно понять, где именно происходит эта перезапись.

1 голос
/ 21 мая 2010

Я помню часть из этого исключения: «Невозможно изменить информацию заголовка - заголовки уже отправлены» в PHP. Это произошло, когда заголовки уже были отправлены в фазе перенаправления, и были сгенерированы любые другие выходные данные, например ::100100

эхо "привет"; заголовок ( "Location: http://stackoverflow.com");

Извините и поправьте меня, если я ошибаюсь, но я все еще изучаю технологии MS, и я пытался помочь.

0 голосов
/ 18 марта 2018

Если у кого-то все еще есть эта проблема. Попробуйте использовать вместо ovverriding

 public void OnActionExecuting(ActionExecutingContext context)
    {
        try
        {

            if (!HttpContext.Current.User.Identity.IsAuthenticated)
            {
                if (!HttpContext.Current.Response.IsRequestBeingRedirected)
                {

                    context.Result = new RedirectToRouteResult(
                new RouteValueDictionary {  { "controller", "Login" }, { "action", "Index" } });
                }
            }

        }
        catch (Exception ex)
        {
               new RouteValueDictionary { { "controller", "Login" }, { "action", "Index" } });
        }

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