IIS 7.0 における ASP.NET アプリケーションのライフ サイクルの概要

Visual Studio 2010

更新 : 2007 年 11 月

このトピックでは、IIS 7.0 の統合モードで実行している、.NET Framework 3.0 以降の ASP.NET アプリケーションのライフ サイクルについて説明します。IIS 7.0 では、クラシック モードもサポートされます。クラシック モードでは、ASP.NET は IIS 6.0 の場合と同じように動作します。詳細については、「IIS 5.0 および 6.0 における ASP.NET アプリケーションのライフ サイクルの概要」を参照してください。

IIS 7.0 統合パイプラインは、ネイティブ コード モジュールとマネージ コード モジュールの両方をサポートする、統合された要求処理パイプラインです。IHttpModule インターフェイスを実装するマネージ コード モジュールは、要求パイプラインのすべてのイベントにアクセスできます。たとえば、ASP.NET Web ページ (.aspx ファイル) と HTML ページ (.htm ファイルまたは .html ファイル) の両方に対する ASP.NET フォーム認証でマネージ コード モジュールを使用できます。HTML ページは IIS および ASP.NET によって静的リソースとして扱われますが、このことは影響しません。IIS 7.0 統合モードの詳細については、「ASP.NET Integration with IIS7」を参照してください。

このトピックは、次のセクションで構成されています。

IIS 7.0 統合モードでは、要求は、IIS 6.0 の ASP.NET リソースに対する要求と同じような段階を通過します。ただし、IIS 7.0 では、これらの段階に MapRequestHandlerLogRequest、および PostLogRequest の各イベントを始めとする追加のアプリケーション イベントがいくつか含まれています。

IIS 7.0 の処理段階と IIS 6.0 の処理段階の主な相違点は、IIS サーバーへの ASP.NET の統合方法にあります。IIS 6.0 では、要求処理パイプラインは 2 つあります。1 つは、ネイティブ コードの ISAPI フィルタおよび拡張コンポーネントに関するものです。もう 1 つは、ASP.NET などのマネージ コード アプリケーション コンポーネントに関するものです。IIS 7.0 では、ASP.NET ランタイムが Web サーバーに統合され、すべての要求が 1 つの統合された要求処理パイプラインで処理されます。統合パイプラインには、ASP.NET 開発者にとって次のような利点があります。

  • 統合パイプラインは、HttpApplication オブジェクトで公開されているすべてのイベントを発生させます。このため、既存の ASP.NET HTTP モジュールを IIS 7.0 統合モードで使用できます。

  • ネイティブ コード モジュールおよびマネージ コード モジュールは、Web サーバー、Web サイト、または Web アプリケーションの各レベルで構成できます。これには、セッション状態、フォーム認証、プロファイル、およびロール管理のための組み込みの ASP.NET マネージ コード モジュールが含まれます。また、要求が .aspx ファイルなどの ASP.NET リソースに対するものかどうかに関係なく、すべての要求についてマネージ コード モジュールを有効または無効にできます。

  • マネージ コード モジュールは、パイプラインの任意の段階で呼び出すことができます。たとえば、要求に対するサーバー処理の発生前、すべてのサーバー処理の発生後、その中間の段階などです。

  • モジュールの登録や、有効と無効の切り替えを行うには、アプリケーションの Web.config ファイルを使用します。

アプリケーションの要求パイプラインの構成は、次の図のようになります。この例には、次の要素が含まれています。

  • Anonymous ネイティブ コード モジュールおよび Forms マネージ コード モジュール (FormsAuthenticationModule に対応)。これらのモジュールは構成されており、要求の Authentication 段階で呼び出されます。

  • Basic ネイティブ コード モジュールおよび Windows マネージ コード モジュール (WindowsAuthenticationModule に対応)。これらは表示されていますが、アプリケーション用に構成されていません。

  • Execute handler 段階。ここで、ハンドラ (モジュール スコープは URL) が呼び出され、応答が作成されます。.aspx ファイルの場合は、PageHandlerFactory ハンドラを使用して要求に応答します。静的ファイルの場合は、ネイティブ コードの StaticFileModule モジュールが要求に応答します。

  • Trace ネイティブ コード モジュール。これは表示されていますが、アプリケーション用に構成されていません。

  • Custom module マネージ コード クラス。これは、Log request 段階で呼び出されます。

IIS 7.0 の要求パイプライン

ASP.NET アプリケーションを旧バージョンの IIS から IIS 7.0 に移行する場合の互換性に関する既知の問題については、「Upgrading ASP.NET 1.1 to IIS7 on Windows Vista & longhorn Beta3」の「Known Differences Between Integrated Mode and Classic Mode」を参照してください。

IIS 7.0 の統合モードにおける ASP.NET アプリケーションのライフ サイクルの各段階を次の表に示します。

段階

説明

アプリケーションのリソースが要求されます。

ASP.NET アプリケーションのライフ サイクルは、ブラウザが Web サーバーに送信する要求から始まります。

IIS 7.0 のクラシック モードおよび IIS 6.0 では、ASP.NET の要求パイプラインは Web サーバーのパイプラインとは分離されます。モジュールは、ASP.NET ISAPI 拡張機能にルーティングされた要求のみに適用されます。要求されたリソースの種類のファイル名拡張子が ASP.NET に明示的に対応付けられていない場合、要求に対して ASP.NET 機能は呼び出されません。これは、要求が ASP.NET ランタイムによって処理されないためです。

IIS 7.0 の統合モードでは、すべての要求が統合パイプラインによって処理されます。統合パイプラインが要求を受け取ると、要求は、すべての要求に共通する各段階を通過します。これらの段階は、RequestNotification 列挙型で表されます。すべての要求は、ASP.NET 機能を利用できるように構成できます。これは、ASP.NET 機能が、要求パイプラインにアクセスできるマネージ コード モジュールにカプセル化されているためです。たとえば、拡張子 .htm は ASP.NET に明示的に対応付けられていませんが、それでも HTML ページに対する要求を実行すると ASP.NET モジュールが呼び出されます。これにより、すべての要求に対して ASP.NET の認証および承認を利用できます。

統合パイプラインは、アプリケーションの最初の要求を受け取ります。

統合パイプラインがアプリケーションのリソースに対する要求を受け取ると、ApplicationManager クラスのインスタンスが作成されます。このインスタンスはアプリケーション ドメインであり、この中で要求が処理されます。アプリケーション ドメインにより、グローバル変数がアプリケーション間で分離され、各アプリケーションを個別にアンロードできるようになります。アプリケーション ドメインには、HostingEnvironment クラスのインスタンスが作成され、アプリケーションに関する情報 (アプリケーションが格納されているフォルダの名前など) にアクセスできるようになります。

最初の要求時に、アプリケーションのトップレベルの項目 (App_Code フォルダのアプリケーション コードなど) を必要に応じてコンパイルします。後の「IIS 7.0 のマネージ コード モジュール」で説明するように、App_Code フォルダにはカスタム モジュールおよびハンドラを含めることができます。

各要求に対する応答オブジェクトが作成されます。

アプリケーション ドメインが作成され、HostingEnvironment オブジェクトのインスタンスが作成された後に、HttpContextHttpRequestHttpResponse などのアプリケーション オブジェクトが作成され、初期化されます。HttpContext クラスには、現在のアプリケーションの要求に固有の HttpRequestHttpResponse などのオブジェクトが含まれます。HttpRequest オブジェクトには、現在の要求に関する情報 (Cookie およびブラウザ情報を含む) が格納されます。HttpResponse オブジェクトには、クライアントに送信される応答 (レンダリングされたすべての出力と Cookie を含む) が格納されます。

.NET Framework 3.0 以降で IIS 7.0 を統合モードで実行する場合と、IIS 6.0 の場合との主な相違点は次のとおりです。

HttpApplication オブジェクトが要求に割り当てられます。

アプリケーションのすべてのオブジェクトが初期化された後に、HttpApplication クラスのインスタンスを作成することにより、アプリケーションが開始されます。アプリケーションに Global.asax ファイルが含まれている場合は、代わりに、HttpApplication クラスから派生する Global.asax クラスのインスタンスが作成されます。この派生クラスを使用して、アプリケーションが表されます。

Bb470252.alert_note(ja-jp,VS.100).gifメモ :
アプリケーションで ASP.NET ページまたはプロセスが最初に要求されたときに HttpApplication クラスの新しいインスタンスが作成されます。ただし、パフォーマンスを最大化するために、HttpApplication のインスタンスを複数の要求で再利用することもできます。

どの ASP.NET モジュール (たとえば、SessionStateModule) が読み込まれるかは、アプリケーションが親アプリケーションから継承したマネージ コード モジュールによって決まります。また、アプリケーションの Web.config ファイルの構成セクションで構成されているモジュールの種類にも依存します。モジュールの追加と削除は、アプリケーションの Web.config の system.webServer セクションにある modules 要素で行います。詳細については、「方法 : IIS 7.0 の <system.webServer> セクションを構成する」を参照してください。

要求は HttpApplication パイプラインによって処理されます。

要求の処理中、HttpApplication クラスで次のタスクが実行されます。要求パイプラインの主要なイベントが発生した場合にコードが実行されるページを開発するには、イベントを使用すると便利です。また、カスタム モジュールを開発していて、パイプラインのすべての要求に対してカスタム モジュールが呼び出されるようにする場合にも使用できます。カスタム モジュールは IHttpModule インターフェイスを実装します。IIS 7.0 の統合モードでは、モジュールの Init メソッドにイベント ハンドラを登録する必要があります。

  1. 要求を検証し、ブラウザが送信する情報を調べ、悪意のあるマークアップが含まれるかどうかを確認します。詳細については、「ValidateRequest」および「スクリプトによる攻略の概要」を参照してください。

  2. Web.config ファイルの UrlMappingsSection セクションで構成されている URL がある場合は、URL マッピングを実行します。

  3. BeginRequest イベントを発生します。

  4. AuthenticateRequest イベントを発生します。

  5. PostAuthenticateRequest イベントを発生します。

  6. AuthorizeRequest イベントを発生します。

  7. PostAuthorizeRequest イベントを発生します。

  8. ResolveRequestCache イベントを発生します。

  9. PostResolveRequestCache イベントを発生します。

  10. MapRequestHandler イベントを発生します。要求されたリソースのファイル名の拡張子に基づいて、適切なアプリケーション ハンドラが選択されます。ハンドラは、IIS 7.0 の StaticFileModule などのネイティブ コード モジュールである場合と、(.aspx ファイルを処理する) PageHandlerFactory クラスなどのマネージ コード モジュールである場合があります。

  11. PostMapRequestHandler イベントを発生します。

  12. AcquireRequestState イベントを発生します。

  13. PostAcquireRequestState イベントを発生します。

  14. PreRequestHandlerExecute イベントを発生します。

  15. 要求に対応する IHttpHandler クラスの ProcessRequest メソッド (または非同期バージョンの IHttpAsyncHandler.BeginProcessRequest) を呼び出します。たとえば、ページを要求している場合は、現在のページのインスタンスが要求を処理します。

  16. PostRequestHandlerExecute イベントを発生します。

  17. ReleaseRequestState イベントを発生します。

  18. PostReleaseRequestState イベントを発生します。

  19. Filter プロパティが定義されている場合は、応答フィルタ処理を実行します。

  20. UpdateRequestCache イベントを発生します。

  21. PostUpdateRequestCache イベントを発生します。

  22. LogRequest イベントを発生します。

  23. PostLogRequest イベントを発生します。

  24. EndRequest イベントを発生します。

  25. PreSendRequestHeaders イベントを発生します。

  26. PreSendRequestContent イベントを発生します。

    Bb470252.alert_note(ja-jp,VS.100).gifメモ :
    MapRequestHandlerLogRequest、および PostLogRequest の各イベントは、アプリケーションが .NET Framework 3.0 以降で IIS 7.0 の統合モードを実行している場合にのみサポートされます。

IIS 7.0 の統合モードにおける Global.asax ファイルの使用は、IIS 6.0 の ASP.NET の場合と同様です。詳細については、「IIS 5.0 および 6.0 における ASP.NET アプリケーションのライフ サイクルの概要」の「ライフ サイクルのイベントと Global.asax ファイル」を参照してください。

相違点としては、MapRequestHandlerLogRequest、および PostLogRequest の各イベントのハンドラを追加できるという点を挙げることができます。これらのイベントは、.NET Framework 3.0 以降で IIS 7.0 の統合モードを実行しているアプリケーションでサポートされます。

Global.asax ファイルでアプリケーション イベント ハンドラを用意して、.aspx ページや .axd ページに対する要求など、ASP.NET で処理されるすべての要求で実行されるコードを追加できます。ただし、ASP.NET 以外のリソースである静的ファイルなどに対する要求では、Global.asax ファイル内のハンドラ コードは呼び出されません。すべてのリソースに対して動作するマネージ コードを実行するには、IHttpModule インターフェイスを実装するカスタム モジュールを作成します。カスタム モジュールは、リソース ハンドラが ASP.NET ハンドラではない場合でも、アプリケーションのリソースに対するあらゆる要求で実行されます。

IIS 7.0 では、次の ASP.NET マネージ コード モジュールを構成して読み込むことができます。

IIS 7.0 のマネージ コード モジュールを構成するには、次のいずれかの方法を使用します。

FormsAuthenticationModule モジュールなどの ASP.NET マネージ コード モジュールを構成して IIS 7.0 に読み込むと、このマネージ コード モジュールは要求パイプラインのすべてのイベントにアクセスできます。つまり、すべての要求がマネージ コード モジュールを通じて渡されるようになります。たとえば、FormsAuthenticationModule クラスの場合、静的コンテンツが ASP.NET ハンドラによって処理されなくても、フォーム認証によってコンテンツを保護できます。

カスタム マネージ コード モジュールの開発

IHttpModule インターフェイスを実装するモジュールを使用して、ASP.NET アプリケーションのライフ サイクルを拡張できます。IHttpModule インターフェイスを実装するモジュールは、マネージ コード モジュールになります。ネイティブ コード モジュールを使用して ASP.NET および IIS 7.0 の統合パイプラインを拡張することもできますが、これについては、このトピックでは扱いません。ネイティブ コード モジュールの詳細およびモジュールの構成方法の概要については、「IIS7 Module Overview」を参照してください。

アプリケーションの App_Code フォルダに格納するクラス ファイルとして、マネージ コード モジュールを定義できます。また、モジュールをクラス ライブラリ プロジェクトとして作成し、これをコンパイルして、アプリケーションの Bin フォルダに追加することもできます。カスタム モジュールを作成したら、IIS 7.0 に登録する必要があります。説明した方法のいずれかを使用して、IIS 7.0 のマネージ コード モジュールを管理できます。たとえば、アプリケーションの Web.config ファイルを編集して、そのアプリケーションについてのみマネージ コード モジュールを登録できます。モジュールの登録方法の例については、「チュートリアル : カスタム HTTP モジュールを作成および登録する」を参照してください。

モジュールがアプリケーションの App_Code フォルダまたは Bin フォルダ内に定義されていて、アプリケーションの Web.config ファイルに登録されている場合、モジュールは、そのアプリケーションでのみ呼び出されます。アプリケーションの Web.config ファイルでモジュールを登録するには、system.webServer セクションの modules 要素を使用します。詳細については、「方法 : IIS 7.0 の <system.webServer> セクションを構成する」を参照してください。IIS マネージャまたは Appcmd.exe ツールを使用して行った変更は、アプリケーションの Web.config ファイルに反映されます。 

マネージ コード モジュールは、IIS 7.0 構成ストア (ApplicationHost.config ファイル) の modules 要素で登録することもできます。ApplicationHost.config ファイルで登録したモジュールにはグローバル スコープが適用され、IIS 7.0 でホストされているすべての Web アプリケーションに対して登録されます。同様に、ApplicationHost.config ファイルの globalModules 要素で定義されているネイティブ コード モジュールにもグローバル スコープが適用されます。Web アプリケーションでグローバル モジュールが必要とされない場合は、無効にすることもできます。

LogRequest イベントおよび PostLogRequest イベントを処理するカスタム モジュールの例を次に示します。イベント ハンドラは、モジュールの Init メソッドで登録されます。

using System;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;

// Module that demonstrates one event handler for several events.
namespace Samples
{
    public class ModuleExample : IHttpModule
    {
        public ModuleExample()
        {
            // Constructor
        }
        public void Init(HttpApplication app)
        {
            app.LogRequest += new EventHandler(App_Handler);
            app.PostLogRequest += new EventHandler(App_Handler);
        }
        public void Dispose()
        {
        }
        // One handler for both the LogRequest and the PostLogRequest events.
        public void App_Handler(object source, EventArgs e)
        {
            HttpApplication app = (HttpApplication)source;
            HttpContext context = app.Context;

            if (context.CurrentNotification == RequestNotification.LogRequest)
            {
                if (!context.IsPostNotification)
                {
                    // Put code here that is invoked when the LogRequest event is raised.
                }
                else
                {
                    // PostLogRequest
                    // Put code here that runs after the LogRequest event completes.
                }
            }

        }
    }
}


アプリケーションの Web.config ファイルでモジュールを登録する方法を次の例に示します。構成セクション内に system.webServer 構成セクションを追加します。

<system.webServer>
  <modules>
    <add name="ModuleExample" type="Samples.ModuleExample"/>
  </modules>
</system.webServer>

カスタム モジュールの作成と登録の方法の例については、「チュートリアル : カスタム HTTP モジュールを作成および登録する」を参照してください。

表示: