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 supportfunción y que se instala como una asignación de script comodín. - Módulo HTTP nativo que llama al
IHttpContext::ExecuteRequestmé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.