子要求は 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 イベントが発生する可能性があります。.BeginRequestEndRequest

この問題が発生する状況

クライアントが特定の 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.