子要求は IIS で重複する ASP.NET イベントを生成します
この記事では、Microsoft インターネット インフォメーション サービス (IIS) の統合パイプライン モード worker プロセス中に子要求によって重複する ASP.NET イベントが作成される、by design ビヘイビアーについて説明します。
元の製品バージョン: Internet Information Services 7.0、8.0、8.5
元の KB 番号: 2901671
現象
統合パイプライン モードを使用するように構成された IIS 7.0 以降のバージョンの IIS があります。 ただし、一部の HyperText Transfer Protocol (HTTP) モジュールやインターネット サーバー アプリケーション プログラム インターフェイス (ISAPI) アプリケーションでは、重複する ASP.NET イベントが発生する可能性があります。.BeginRequest
EndRequest
この問題が発生する状況
クライアントが特定の URL (Web ページ) を要求した場合、IIS はサーバー側で同じ URL または別の URL を再要求することがあります。 クライアントの元の要求は 親要求と呼ばれ、IIS が実行する要求は 子要求と呼ばれます。
たとえば、次の両方の子要求を実行できます。
- 関数を使用
HSE_REQ_EXEC_URL support
し、ワイルドカード スクリプト マップとしてインストールされる ISAPI 拡張機能。 - メソッドを呼び出す
IHttpContext::ExecuteRequest
ネイティブ HTTP モジュール。
HSE_REQ_EXEC_URL
は、ISAPI 拡張機能が URL 要求を書き換えて別の拡張機能を呼び出したり、構造体を使用 HSE_EXEC_URL_INFO
して元の URL を呼び出したりできるようにします。 子要求を呼び出す場合は、構造体メンバーの HSE_EXEC_URL_INFO
pszUrl を子 URL の URI ステムに設定します。 元の URL を呼び出す場合は、NULL に設定pszUrl
します。 ISAPI 拡張機能に HSE_REQ_EXEC_URL
加えて、メソッドは IHttpContext::ExecuteRequest
パラメーターにインターフェイスを IHttpContext
指定して子要求を pHttpContext
実行します。
親要求と子要求の両方が、統合パイプライン モードのワーカー プロセスで実行される ASP.NET に接続されたアプリケーションをターゲットとする場合、重複する ASP.NET イベントが生成される可能性があります。 この動作は、失敗した要求イベント バッファリング (FREB) を使用して確認できます。 これは、失敗した要求トレースとも呼ばれます。
ログ
次のログ エントリは、/parent.aspx に対するクライアント要求を示しています。
イベント | 情報 |
---|---|
GENERAL_REQUEST_START | SiteId="1", AppPoolId="DefaultAppPool", ConnId="610612739", RawConnId="0", RequestURL="http://localhost:80/parent.aspx", RequestVerb="GET" |
次のログ エントリは、 BEGIN_REQUEST
global.asax の通知が /parent.aspx への要求によってトリガーされることを示しています。 これは最初 BEGIN_REQUEST
の通知です。
イベント | 情報 |
---|---|
NOTIFY_MODULE_START | ModuleName="global.asax", Notification="BEGIN_REQUEST", fIsPostNotification="false" |
AspNetStart | Data1="GET", Data2="/parent.aspx", Data3="" |
次のログ エントリは、ネイティブ HTTP モジュール (myhttpmodule.dll) が実行され、子要求である child.aspx が実行されることを示しています。
イベント | 情報 |
---|---|
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" |
次のログ エントリは、global.asax の通知が /child.aspx への要求によってトリガーされることを BEGIN_REQUEST
示しています。 これは 2 番目 BEGIN_REQUEST
の通知です。
イベント | 情報 |
---|---|
NOTIFY_MODULE_START | ModuleName="global.asax", Notification="BEGIN_REQUEST", fIsPostNotification="false" |
AspNetStart | Data1="GET", Data2="/child.aspx", Data3="" |
次のログ エントリは、global.asax の通知が /child.aspx への要求によってトリガーされることを示しています END_REQUEST
。 これは最初のEND_REQUEST通知です。
イベント | 情報 |
---|---|
NOTIFY_MODULE_START | ModuleName="global.asax", Notification="END_REQUEST", fIsPostNotification="false" |
AspNetPipelineEnter | Data1="ASP.global_asax" |
AspNetPipelineLeave | Data1="ASP.global_asax" |
次のログ エントリは、子要求が完了したことを示しています。
イベント | 情報 |
---|---|
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="操作は正常に完了しました。 (0x0)" |
AspNetEnd |
次のログ エントリは、global.asax の通知が /parent.aspx への要求によってトリガーされることを END_REQUEST
示しています。 これは 2 番目 END_REQUEST
の通知です。
イベント | 情報 |
---|---|
NOTIFY_MODULE_START | ModuleName="global.asax", Notification="END_REQUEST", fIsPostNotification="false" |
AspNetPipelineEnter | Data1="ASP.global_asax" |
AspNetPipelineLeave | Data1="ASP.global_asax" |
次のログ エントリは、親要求が完了したことを示しています。
イベント | 情報 |
---|---|
GENERAL_REQUEST_END | BytesSent="332", BytesReceived="266", HttpStatus="200", HttpSubStatus="0" |
関連情報
子要求を実行するメソッドを ExecuteRequest
呼び出す方法の詳細については、「 IHttpContext::ExecuteRequest メソッド」を参照してください。
このサンプル コードでは、親要求は 、子要求は /default.aspx
/example/default.aspx
.