Las solicitudes secundarias generan eventos ASP.NET duplicados en IIS

En este artículo se describe un comportamiento por diseño que los eventos ASP.NET se crean mediante solicitudes secundarias durante el proceso de trabajo del modo de canalización integrado en Microsoft Internet Information Services (IIS).

Versión del producto original:   Internet Information Services 7.0, 8.0, 8.5
Número KB original:   2901671

Síntomas

Tiene IIS 7.0 o una versión posterior de IIS configurada para usar el modo de canalización integrado. Sin embargo, algunos módulos del Protocolo de transferencia de hipertexto (HTTP) o aplicaciones de la Interfaz de programa de aplicaciones de Internet Server (ISAPI) BeginRequest pueden desencadenar eventos ASP.NET duplicados como y EndRequest.

Situaciones en las que se produce este problema

Cuando un cliente solicita una dirección URL específica (página web), IIS a veces puede volver a solicitar la misma dirección URL u otra dirección URL en el lado del servidor. La solicitud original del cliente se denomina solicitud primaria y la solicitud que ejecuta IIS se denomina solicitud secundaria.

Por ejemplo, ambos pueden ejecutar una solicitud secundaria:

  • Una extensión ISAPI que usa la HSE_REQ_EXEC_URL support función y que se instala como una asignación de script comodín.
  • Módulo HTTP nativo que llama al IHttpContext::ExecuteRequest método.

HSE_REQ_EXEC_URL permite que una extensión ISAPI reescriba una solicitud de dirección URL para llamar a otra extensión o para llamar a la dirección URL original mediante la HSE_EXEC_URL_INFO estructura. Si invoca la solicitud secundaria, establece pszUrl del HSE_EXEC_URL_INFO miembro de la estructura en la raíz uri de la dirección URL secundaria. Si llama a la dirección URL original, se establece pszUrl en NULL. Además de la extensión HSE_REQ_EXEC_URL ISAPI, IHttpContext::ExecuteRequest el método ejecuta la solicitud secundaria especificando la IHttpContext interfaz en el pHttpContext parámetro.

Cuando la solicitud principal y la solicitud secundaria tienen como destino una aplicación conectada ASP.NET que se ejecuta en el proceso de trabajo del modo de canalización integrado, se pueden generar eventos ASP.NET duplicados. Puede confirmar este comportamiento mediante el búfer de eventos de solicitud con error (FREB). Esto también se conoce como Seguimiento de solicitudes con error.

Registros

La siguiente entrada de registro muestra las solicitudes de cliente a /parent.aspx:

Evento Información
GENERAL_REQUEST_START SiteId="1", AppPoolId="DefaultAppPool", ConnId="610612739", RawConnId="0", RequestURL="http://localhost:80/parent.aspx", RequestVerb="GET"

La siguiente entrada de registro muestra que una BEGIN_REQUEST notificación en global.asax se desencadena mediante una solicitud a /parent.aspx. Esta es la primera notificación BEGIN_REQUEST :

Evento Información
NOTIFY_MODULE_START ModuleName="global.asax", Notification="BEGIN_REQUEST", fIsPostNotification="false"
AspNetStart Data1="GET", Data2="/parent.aspx", Data3=""

La siguiente entrada de registro muestra que se ejecuta el módulo HTTP nativo (myhttpmodule.dll) y que ejecuta la solicitud secundaria, child.aspx:

Evento Información
NOTIFY_MODULE_START ModuleName="myhttpmodule", Notification="MAP_PATH", fIsPostNotification="false"
GENERAL_CHILD_REQUEST_START SiteId="1", RequestURL=""http://localhost:80/child.aspx, RequestVerb="GET", RecursiveLevel="1"
GENERAL_REQUEST_START SiteId="1", AppPoolId="DefaultAppPool", ConnId="1610612739", RawConnId="0", RequestURL="http://localhost:80/child.aspx", RequestVerb="GET"

La siguiente entrada de registro muestra que BEGIN_REQUEST la notificación en global.asax se desencadena mediante una solicitud a /child.aspx. Esta es la segunda BEGIN_REQUEST notificación:

Evento Información
NOTIFY_MODULE_START ModuleName="global.asax", Notification="BEGIN_REQUEST", fIsPostNotification="false"
AspNetStart Data1="GET", Data2="/child.aspx", Data3=""

La siguiente entrada de registro muestra que la END_REQUEST notificación en global.asax se desencadena mediante una solicitud a /child.aspx. Esta es la primera notificación END_REQUEST:

Evento Información
NOTIFY_MODULE_START ModuleName="global.asax", Notification="END_REQUEST", fIsPostNotification="false"
AspNetPipelineEnter Data1="ASP.global_asax"
AspNetPipelineLeave Data1="ASP.global_asax"

La siguiente entrada de registro muestra que la solicitud secundaria finaliza:

Evento Información
GENERAL_REQUEST_END BytesSent="332", BytesReceived="266", HttpStatus="200", HttpSubStatus="0"
GENERAL_CHILD_REQUEST_END BytesSent="332", HttpStatus="200", HttpSubStatus="0"
NOTIFY_MODULE_COMPLETION ModuleName="myhttpmodule", Notification="MAP_PATH", fIsPostNotificationEvent="false", CompletionBytes="0", ErrorCode="The operation completed successfully. (0x0)"
AspNetEnd

La siguiente entrada de registro muestra que END_REQUEST la notificación en global.asax se desencadena mediante una solicitud a /parent.aspx. Esta es la segunda END_REQUEST notificación:

Evento Información
NOTIFY_MODULE_START ModuleName="global.asax", Notification="END_REQUEST", fIsPostNotification="false"
AspNetPipelineEnter Data1="ASP.global_asax"
AspNetPipelineLeave Data1="ASP.global_asax"

La siguiente entrada de registro muestra que finaliza la solicitud primaria:

Evento Información
GENERAL_REQUEST_END BytesSent="332", BytesReceived="266", HttpStatus="200", HttpSubStatus="0"

Referencias

Para obtener más información acerca de cómo llamar al método ExecuteRequest para ejecutar la solicitud secundaria, vea Método IHttpContext::ExecuteRequest.

En este código de ejemplo, la solicitud principal es /default.aspxy la solicitud secundaria es /example/default.aspx.