Как узнать, когда 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);
}