2010-03-04 11 views
14

Para resumir, tengo una aplicación ASP.NET que estoy tratando de depurar y en algún momento, en circunstancias muy particulares, la aplicación lanzar excepciones en un Response.Redirect() indicando:¿Cómo puedo saber cuándo se han enviado encabezados HTTP en una aplicación ASP.NET?

"Cannot redirect after HTTP headers have been sent." 

Cosa que más o menos get, excepto que no puedo averiguar donde se enviaron los encabezados.

¿Hay algo que buscar en una aplicación ASP.NET que indique que se han enviado los encabezados HTTP?

DIFICULTAD DE BONIFICACIÓN: La aplicación de ASP.NET todavía está en .NET 1.1. Las circunstancias con respecto a la demora detrás de la actualización son un tema realmente doloroso.

+0

Respuesta búfer ('Response.Buffer' - usted quiere esto en) y la respuesta de enrojecimiento (' Response.Flush() '- que Don no quiero hacer esto) son dos candidatos obvios. – bzlm

Respuesta

15

tiene un evento PreSendRequestHeaders que se llama justo cuando los encabezados están escritos. Suscríbase a esto y regístrese o agregue un punto de interrupción.

Más allá de eso, HttpResponse tiene una propiedad llamada internaHeadersWritten (_headersWritten campo en .NET 1.1). Como es interno, no puedes acceder directamente, pero puedes hacerlo a través de la reflexión. Si esto es solo para la depuración interna (es decir, no el código de producción), entonces está bien usar el reflejo.

Compruebe este método antes/después de todos los eventos de lifecylce de la página. Una vez que sepa qué evento está escribiendo los encabezados, agregue más verificaciones HeadersWritten para averiguar dónde se están escribiendo. A través del estrechamiento progresivo de los controles a esta propiedad, lo encontrará.

Nueva información

HeadersWritten propiedad es público a partir de .Net 4.5.2

+0

Esto se ve muy bien ... excepto que olvidé mencionar que la aplicación está en .NET 1.1 y parece ser una solución .NET 2.0+. –

+0

@Schnapple, .NET 1.1 es realmente viejo. Siempre debe especificar la versión cada vez que esté hablando de una versión anterior. En .NET 1.1 había solo un campo privado, '_headersWritten', que puedes leer a través de la reflexión. –

+2

'HeadersWritten' propiedad es pública a partir de .Net 4.5.2 –

5

la respuesta de Samuel acaba de resolverse este problema para mí (1). No puedo pegar un ejemplo de código en un comentario, pero en aras de ayudar a los demás, así es como yo solía caso sugirió añadir una propiedad HeadersWritten a mi 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(); 
} 

En mi código que rompería si me lío con las cabeceras demasiado tarde, simplemente comprobar la propiedad HeadersWritten primera:

if (!HeadersWritten) 
{ 
    Context.Response.StatusDescription = get_custom_description(Context.Response.StatusCode); 
} 
+4

Tenga en cuenta que cada instancia de un objeto 'HttpApplication' puede servir varias solicitudes (pero siempre secuenciales), por lo que * debe * restablecer el indicador durante el evento BeginRequest. Esto también se aplica a un 'HTTPHandler' que tiene la propiedad' IsReusable' devolviendo verdadero. Consulte [HttpApplication] (http://msdn.microsoft.com/en-us/library/system.web.httpapplication.aspx) y [IsResuable] (http://msdn.microsoft.com/en-us/library/ system.web.ihttphandler.isreusable.aspx) en MSDN para más detalles. –

+0

Gracias por eso, Euro. Para que quede claro, agrego esta propiedad y los códigos y eventos asociados a mi clase que hereda de IHttpHandler. Tenía entendido que esta clase debería ser de un solo uso para esta solicitud y, por lo tanto, estar totalmente a salvo de la interferencia de otras solicitudes. Si esta comprensión no es correcta, ¡házmelo saber! –

+0

Uno de los miembros de la interfaz IHttpHandler es una propiedad llamada 'IsReusable' (lo escribí mal en mi comentario original). Si su implementación es esencialmente 'public bool IsReusable {get {return false; }} ', entonces está bien: ASP.NET instanciará un objeto para cada solicitud y luego lo descartará. Si devuelve 'true', ASP.NET volverá a utilizar sus instancias para múltiples solicitudes y no estará seguro para subprocesos. –

Cuestiones relacionadas