Как узнать, когда HTTP-заголовки были отправлены в приложении ASP.NET?
Короче говоря, у меня есть приложение ASP.NET, которое я пытаюсь отлаживать, и в какой-то момент, в особых обстоятельствах, приложение будет генерировать исключения в Response.Redirect()
, заявляя:
"Cannot redirect after HTTP headers have been sent."
Что я более или менее получаю, кроме того, что я не могу понять, куда были отправлены заголовки.
Есть ли что-то, что нужно искать в приложении ASP.NET, которое укажет, что отправлены заголовки HTTP?
BONUS DIFFICULTY: Приложение ASP.NET все еще находится в .NET 1.1. Обстоятельства, связанные с задержкой по обновлению, являются очень болезненным предметом.
Ответы
Ответ 1
HttpApplication
имеет событие PreSendRequestHeaders
, которое вызывается только тогда, когда заголовки являются writtne. Подпишитесь на это и зарегистрируйте его или добавьте точку останова.
Кроме того, HttpResponse
имеет свойство internal, называемое HeadersWritten
(_headersWritten
в .NET 1.1). Поскольку он внутренне, вы не можете получить к нему доступ напрямую, но вы можете через отражение. Если это только для внутренней отладки (т.е. Не для производственного кода), тогда хорошо использовать отражение.
Проверить этот метод до/после всех событий lifecylce на странице. Как только вы узнаете, какое событие выписывает заголовки, добавьте больше проверок HeadersWritten
, чтобы узнать, где они пишутся. Через прогрессивное сужение чеков к этому имуществу вы найдете его.
Новая информация
HeadersWritten
свойство является общедоступным, начиная с .Net 4.5.2
Ответ 2
Сэмюэл ответил, что решил эту проблему для меня (+1). Я не могу вставить образец кода в комментарий, но в интересах помощи другим, здесь, как я использовал событие, он предложил добавить свойство HeadersWritten в мой IHTTPHandler:
protected bool HeadersWritten { get; private set; }
void ApplicationInstance_BeginRequest(object sender, EventArgs e)
{
HeadersWritten = false;
}
void ApplicationInstance_PreSendRequestHeaders(object sender, EventArgs e)
{
HeadersWritten = true;
}
public void ProcessRequest(HttpContextBase context)
{
context.ApplicationInstance.PreSendRequestHeaders += new EventHandler(ApplicationInstance_PreSendRequestHeaders);
do_some_stuff();
}
В моем коде, который сломался бы, если я испортил заголовки слишком поздно, я сначала проверю свойство HeadersWritten:
if (!HeadersWritten)
{
Context.Response.StatusDescription = get_custom_description(Context.Response.StatusCode);
}