***
ASP.NET MVCが着信要求を処理するときにランタイムモードで何が起こるかを見てみましょう。
ASP.NET MVCのクエリ処理パイプラインは、システムの構造を表示するという点で、ASP.NET WebFormsのページライフサイクルに匹敵します。 非標準のタスクを実行するには、このプロセスの理解が必要です。 ASP.NETの従来のページライフサイクルとは異なり、MVCのリクエスト処理パイプラインは非常に柔軟です。必要に応じてその一部を変更したり、一部のコンポーネントを再配布または置換したりできます。 通常、パイプラインを拡張または変更する必要はありませんが、ASP.NET MVCの中核には拡張性があるため、いつでもこれを行うことができます。
この図は、リクエスト処理パイプラインの図を示しています。 中心軸は標準のパイプラインです(ビューをレンダリングするクエリの場合)。 ブランチは拡張の主要なポイントです。 スキームを単純化するために、すべてのステージと拡張ポイントが絶対に含まれているわけではありません。 最も重要な省略は、アクションメソッドの実行の前後に、またはアクション結果の実行の前後に埋め込むことができるフィルターです。
ステップ1:IIS
MicrosoftのWebサーバーであるインターネットインフォメーションサービス(IIS)が最初に起動します。 HTTP要求が到着すると、ASP.NETが届く前に、WindowsカーネルHTTP.SYSドライバーはURL /ポート番号/ IPアドレスの組み合わせを分析し、それらを照合して、登録済みアプリケーション(IIS WebサイトまたはIIS Webサイト内の仮想ディレクトリ)。
ASP.NET MVCアプリケーションはASP.NETに基づいているため、アプリケーションプールに対してASP.NETを有効にする必要があります(各IISアプリケーションは特定のアプリケーションプールに関連付けられています)。 ASP.NETは、2つのマネージパイプラインモードで有効にできます。
•ISAPIモード(クラシックモード)では、URLの特定のファイル拡張子(.aspx、.ashx、.mvcなど)に関連付けられたISAPI拡張子(aspnet_isapi.dll)を使用してASP.NETがアクティブ化されます。 IIS 6では、ワイルドカードを使用でき、aspnet_isapi.dllはファイル拡張子に関係なくすべての要求を処理します。
•統合モード(IIS 7以降でのみサポート):NETは要求処理パイプラインのネイティブ部分であるため、ファイル拡張子に関連付けられたISAPI拡張を使用する必要はありません。 これにより、 "美しい" URL(ファイル拡張子なし)を使用したルーティングが簡単になります。
いずれの場合も、ASP.NETシステムは着信要求を受け入れるとすぐに、登録されたすべてのHTTPモジュールに新しい要求が到着したことを通知します。 (HTTPモジュールはIHttpModuleインターフェイスを実装する.NETクラスであり、リクエスト処理パイプラインに「埋め込む」ことができます)。 すべてのASP.NET MVCアプリケーションでデフォルトで登録されている特に重要なHTTPモジュールの1つはUrlRoutingModuleです。 このモジュールは、ルーティングシステム全体(コアルーティングシステム)の開始点です。 IIS 6の場合、UrlRoutingModuleモジュールはweb.configファイルに登録されます。
IIS 7では、モジュールGUIを使用できます(これを行うには、管理ツールからインターネットインフォメーションサービス(IIS)マネージャーを開き、Webサイトを選択して、[モジュール]をダブルクリックします)。
ステップ2:コアルーティング
UrlRoutingModuleモジュールが要求処理に入ると、System.Web.Routingルーティングシステムが起動します。 ルーティングタスクは、着信URLを認識および解析し、後続のコンポーネントで使用できる要求コンテキストを入力します(たとえば、ASP.NET MVCは、それを使用して、対応するMVCに制御を転送し、アクションメソッドのパラメーターを入力します)。
この図は、まずルーティングシステムが、着信URLがディスク上のファイルと一致するかどうかをチェックすることを示しています。 その場合、ルーティングシステムは終了し、IISは要求の処理を続行します。 静的ファイル(例:.gif、.jpeg、.png、.css、または.js)の場合、これはIISが標準的な方法で処理することを意味します(ディスク上に存在するため)。これは非常に効率的です。 同様に、従来のASP.NET WebForms(.aspx)ページは通常の方法で処理されます。
ただし、着信URLがディスク上のファイル(たとえば、ファイルではなく.NETクラスであるMVCへの要求)と一致しない場合、ルーティングシステムは着信URLを処理する方法を決定するために現在の構成を調べます。
ルーティングテーブル
ルーティングテーブルは、静的コレクションSystem.Web.Routing.RouteTable.Routesに保存されます。 コレクション内の各エントリは、有効なURLのテンプレートです。 テンプレートには、オプションでプレースホルダー(/ blog / {year} / {entry}など)および各パラメーターの許容値の範囲を制限する制約を含めることができます。 各エントリは、要求を受け入れて処理するIRouteHandlerインターフェイスを実装するオブジェクトであるルートハンドラーを指します。 RouteTable.Routesコレクションを作成するには、適切なコードをGlobal.asax.csファイルのRegisterRoutes()メソッドに追加する必要があります。
HTTPリクエストがRouteTable.Routesの特定のルートと一致するかどうかを確認するために、ルーティングシステムはRouteTable.Routesコレクションを上から下へスキャンし始め、着信リクエストと一致する最初のルートを選択します。 それを見つけると、ルーティングシステムはルートハンドラーに制御を移し、選択されたルートとすべてのURLパラメーターを記述する要求コンテキストを提供します。
ステップ3:コントローラーとアクション
この時点で、ルーティングシステムはRouteTable.Routesコレクションからルートを選択し、URLパラメーターを分析しました。 この情報はすべて、リクエストのコンテキストに配置されます。 では、コントローラーとアクションはどこからシーンに入りますか?
コントローラーの検索と開始
ASP.NET MVCアプリケーションの場合、RouteTable.Routesからのほとんどのルートは、1つのハンドラー-MvcRouteHandlerハンドラーに対応します;これは、ASP.NET MVCに組み込まれた標準ハンドラーです。 MvcRouteHandlerは、要求コンテキストを使用して適切なコントローラーを呼び出す方法を知っています。
図でわかるように、彼はコントローラーファクトリを使用してこれを行います。 デフォルトでは、DefaultControllerFactoryという非常にオリジナルなファクトリーを使用します。このファクトリーは、特定のコントローラー命名規則を使用して、着信要求に適切なコントローラーを選択します。
ただし、DefaultControllerFactoryビルトインファクトリをIControllerFactoryインターフェイスのその他の実装またはDefaultControllerFactoryクラスの継承で置き換える場合、このロジックを変更する必要があります。
コントローラーがすべきこと
コントローラークラスの最小要件は、IControllerインターフェイスを実装する必要があることです。
パブリックインターフェイスIController
{
void Execute(RequestContext requestContext);
}
ご覧のとおり、これは非常にシンプルなインターフェイスです! コントローラーがExecute()メソッドで何かを行う必要があることを除いて、何も定義しません。 requestContextパラメーターは、URLパラメーターを含む、ルーティングシステムによって生成された要求コンテキストに関する完全な情報を格納し、さらに、RequestおよびResponseオブジェクトへのアクセスを提供することに注意してください。
コントローラーが通常行うこと
ほとんどの場合、IControllerを直接実装する必要はありません。System.Web.Mvc.Controllerクラスからコントローラーを継承できます。 これは、要求の処理に必要なインフラストラクチャを追加する標準のASP.NET MVCベースコントローラーです。 最も重要なことは、アクションメソッドをシステムに導入することです。 これは、すべてのパブリックコントローラーメソッドがURL経由で到達可能であることを意味し(このようなメソッドは "アクションメソッド"と呼ばれます)、さらに、これは自分でExecute()メソッドを実装する必要がないことを意味します。
アクションメソッドはHTTP応答に直接出力できますが、これは推奨されません。 アクションメソッドでのコードのテストと再利用の利便性の理由から、アクションの結果を記述するアクション結果(ActionResultから継承されたオブジェクト)を返すことをお勧めします。 たとえば、ビューをレンダリングする場合は、ViewResultを返す必要があります。 または、HTTP要求を別のアクションメソッドにリダイレクトするには、RedirectToRouteResultを返す必要があります。 ASP.NET MVCは、リクエスト処理パイプラインで適切なタイミングで結果を配信します。
さらに、非常に柔軟なフィルターシステム(フィルター)があります。 これらは、アクションメソッドの実行前または実行後、またはアクション結果の実行前または実行後にロジックを埋め込むことにより、コントローラークラスまたはアクションメソッドをマークできる.NET属性([Authorize]など)です。 例外フィルターや許可フィルターなど、いくつかの組み込みフィルターがあります。 フィルターは非常に多くの異なる場所で使用できるため、サーキットで場所を見つけることができませんでした!
コントローラーとアクション(および関連する機能)は、ASP.NET MVCの重要な概念です。
ステップ4:アクションの結果とビュー
はい、はい、かなり多くのことが起こりました! 繰り返しましょう:
•ルーティングシステムは、着信URLを特定のルートにマップし、要求コンテキストを含むオブジェクトを準備しました。 RouteTable.Routesから選択されたルートは、リクエストを処理するMvcRouteHandlerハンドラーを指定しました。
•MvcRouteHandlerは、要求コンテキストとコントローラーファクトリを使用して、適切なコントローラーを選択して呼び出します。
•コントローラーがアクションメソッドの1つを呼び出しました。
•アクションメソッドがActionResultオブジェクトを返しました。
この時点で、ASP.NET MVCはActionResultの結果を起動します。
プレゼンテーションのレンダリング
ActionResultから継承された1つの特別なクラスであるViewResultに特に注意を払います。 このクラスは、アクションメソッドで形成されたViewDataコレクションに何かを渡すことで、対応するプレゼンテーションテンプレートを見つけてレンダリングできます。 これは、「ビューエンジン」(IViewEngineインターフェイスを実装する.NETクラス)と呼ばれるものです。
標準エンジンはWebFormViewEngineです。 そのプレゼンテーションテンプレートは、WebForms(.aspx)ページ(つまり、従来のASP.NET WebFormsテクノロジで使用されるサーバーページ)です。 WebFormsページには独自の処理パイプラインがあり、ASPX / ASCXをオンザフライでコンパイルし、ページライフサイクルと呼ばれる一連のイベントを実行します。 従来のASP.NETとは異なり、ASP.NET MVCでは、これらのページはできるだけシンプルにする必要があります。MVCの原則によれば、ビューはHTMLコードの生成のみを担当するためです。 つまり、WebFormsページのライフサイクルを詳細に理解する必要はありません。 役割の分離の原則を遵守することで、コード保守の単純さと利便性が実現します。
***
記事「 13 ASP.NET MVCの拡張ポイントを知っておく必要があります」は、このトピックに直接役立つと思います 。