English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
前回はAsp.Netのルートシステムを解析しました。今日は、WebHost方式でデプロイされたAsp.Net Web APIのルートシステムが内部でどのように実現されているかを簡単に解析します。それでは、簡単な例から始めましょう。
空のWebApiプロジェクトを作成し、Globalにルート情報を登録します:
public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { //登録ルート GlobalConfiguration.Configuration.Routes.MapHttpRoute( name: "default", routeTemplate: "api"/{controller}/{id}", defaults: new { id = RouteParameter.Optional }); } }
Homeという名前のControllerを作成します:
public class HomeController : ApiController { // GET: api/Home public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } // GET: api/Home/5 public string Get(int id) { return "value"; } }
起動して実行し、ブラウザのアドレスバーにhttp:を入力して確認します。//localhost:46351/api/homeとhttp://localhost:46351/api/home/5結果は以下の通りです:
Asp.Net Web APIのインスタンスを簡単に確認した後、Asp.Net Web APIのルートシステムを分析し始めましょう。
まず、Asp.Net Web APIのルーティングの登録方法を見てみましょう:
このルーティング登録プロセスでは、どのような操作が隠されていますか?以下のソースコードを見てみましょう:
ソースコードを確認することで、Asp.Net Web APIのルーティングの登録はHttpRouteCollection型の拡張メソッドMapHttpRouteによって実現されていることがわかります。MapHttpRouteメソッドの中で、作成されたルートオブジェクトがHttpRouteCollectionオブジェクトのAddメソッドを呼び出して保存されています。GlobalConfigurationの静的属性ConfigurationはHostedHttpRouteCollection型でRouteTable.Routesをコンストラクタの引数として作成されており、HostedHttpRouteCollection型はHttpRouteCollection型のサブクラスであるため、HostedHttpRouteCollection型では、サブクラスHostedHttpRouteCollectionが親クラスのAddメソッドとCreateRouteメソッドをオーバーライドしています。以下の図のように、実際に作成されたルートオブジェクトの型はHostedHttpRouteです。このルートオブジェクトはグローバルルートテーブルに保存されています。ここから、グローバルルートテーブルに保存されているルートオブジェクトの型がHostedHttpRouteであることがわかります。それでは、グローバルルートテーブルに保存されたルートオブジェクトを登録する意味は何でしょうか、後続部分で分析します。
上のソースコードからは、最終的に作成されたルートオブジェクトがHostedHttpRouteタイプであることがわかります。それでは、前でルートを登録した際にRouteHandlerとHttpHandlerを指定していなかったため、どこからそれらがルートオブジェクトに追加されたのか、またHostedHttpRouteオブジェクトの作成プロセスで隠された秘密は何かを次にソースコードを確認してみましょう:
上記の分析を通じて、現在までにAsp.Net Web APIがWebHost方式でホストされる場合、登録されたルートオブジェクトがHostedHttpRouteタイプのインスタンスであり、グローバルルートテーブルRouteTable.Routesに保存されています。リクエストを処理するRouteHandlerとHttpHandlerはそれぞれHttpControllerRouteHandlerタイプのインスタンスとHttpControllerHandlerタイプのインスタンスです。
ルート情報を登録した後、Asp.Net Web APIではどのようにして登録したルート情報をルーティングに利用するのでしょうか?Asp.Netと同様にHttpModuleを通じて実現されるのでしょうか。プログラムを起動してGlobalクラスのModules属性を見てみましょう:
上のスクリーンショットからは明確にわかりますように、Asp.Net Web APIがWebHost方式でサービスをホストする場合、ASP.Netと同様にUrlRoutingModuleを通じてルーティングが行われます。前回のAsp.Netルーティングシステムの分析を参照すると、Asp.NetはUrlRoutingModuleを通じてリクエストをインターセプトし、次にグローバルルートテーブルから順次マッチングを行い、リクエストUrlにマッチするRouteDataを取得して以降の処理に進めることができます。Asp.Net Web APIでは、上記の内容から、グローバルルートテーブルに保存されているルートオブジェクトがHostedHttpRouteタイプであることを知ることができます。そこで、Asp.Net Web APIで最終的にどのようにしてマッチするRouteDataを取得するのかをさらに分析しましょう。
UrlRoutingModuleの中で、RouteDataは各ルートオブジェクトのGetRouteDataメソッドを順次呼び出して取得されます。Asp.Net Web APIでは、ルートオブジェクトのタイプがHostedHttpRouteであるため、GetRouteDataメソッドの呼び出し時の動作を見てみましょう:
HostedHttpRouteでは、OriginalRoute属性のGetRouteDataメソッドを通じてRouteDataを取得しています。前文の分析から、このOriginalRoute属性はHttpWebRouteタイプであることがわかります。
上記の分析から、Asp.Net Web APIがWebHostモードでデプロイされている場合、最終的にはAsp.Netのルートシステムがマッチング作業を完了することがわかります。ただし、HttpWebRouteの親クラスの検証制約メソッドをオーバーライドしているため、制約の検証はAsp.Net Web APIが独自の方法で制約のマッチングを検証しています。
最後に、RouteDataオブジェクトとその中に含まれるRouteHandler、HttpHandlerを一連の作業を通じて取得すると、Asp.Net Web APIはこれらを利用してリクエストの処理と応答を行うことができます。
まとめ:
上記の分析を通じて、以下の結論が導き出されます:Asp.Net Web APIがWebHostモードでデプロイされている場合、登録されたルートはグローバルルートテーブルに保存されます。RouteDataを取得する際には、Asp.Netルートシステムのマッチングルールに基づいてルートマッチングが行われますが、独自の制約検証ルールを実現しています。
これで本稿のすべての内容が終わりです。皆様の学習に役立つことを願っています。また、呐喊チュートリアルを多くの皆様に支持していただけると幸いです。
声明:本稿の内容はインターネットから取得しており、著作権者に帰属します。インターネットユーザーが自発的に貢献し、アップロードしたものであり、本サイトは所有権を有しておらず、人工的な編集は行われていません。著作権侵害を疑う内容がある場合は、メールで notice#w までお知らせください。3codebox.com(メールを送信する際、#を@に置き換えてください。告発を行い、関連する証拠を提供してください。一旦確認が取れたら、本サイトは即座に侵害を疑われるコンテンツを削除します。)