ASP.NET MVC4 の Web API を学んでみる その5 〜Self Host編〜
その1〜その4 では、ASP.NET ランタイム上で ASP.NET Web API を動作するいくつかのTIPS方法を紹介した。今回は、Self-Host と呼ばれる機能を利用して、ASP.NET ランタイム上でなく .NET Framework 上で直に ASP.NET Web API を動作させる方法を紹介する。
様々な用途が存在すると思われるが、今回紹介する方法を利用すれば、Windows Azure 上で Web Role を利用せず、 Worker Role のみを利用して容易に公開 Web API を構築することが可能だと思われる(未検証)。
ASP.NET Web API の Self-Host アプリを作成する
まず、Visual Studio を"管理者権限"で起動し、メニューから「コンソールアプリケーション」を新規に作成する(サンプルは WebApiConsoleApp をソリューション名とした)。
次に、「ソリューション エクスプローラ」を右クリックし、メニューから「NuGet パッケージの管理」を選択してパッケージ管理のウィザードを起動する。
左側のメニューから「オンライン」を選択し、右上の検索ボックスに「SelfHost」を入力し、検索結果から次の画像に従って「Microsoft ASP.NET Web API Self」をインストールする。
更に「ソリューションエクスプローラ」の「参照設定」を右クリックし、次の画像に従って「System.Web」の参照設定を追加する。
参照設定完了後、プロジェクトに「Controllers」フォルダを作成し、同フォルダ以下に「Web API コントローラークラス」を新規に作成する。特に生成内容からの変更はしていないが(using の整理のみ実施)、ソースコードは以下となる。
using System.Collections.Generic; using System.Web.Http; namespace WebApiConsoleApp.Controllers { public class ValuesController : ApiController { // GET api/<controller> public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } // GET api/<controller>/5 public string Get(int id) { return "value"; } // POST api/<controller> public void Post([FromBody]string value) { } // PUT api/<controller>/5 public void Put(int id, [FromBody]string value) { } // DELETE api/<controller>/5 public void Delete(int id) { } } }
最後に、Self-Host として公開する処理を Program.cs に記載する。System.Web.Http.SelfHost.HttpSelfHostServer クラスを利用することで、プログラム内で設定したルーティング情報に従って ASP.NET Web API 可能だ。
using System; using System.Web.Http; using System.Web.Http.SelfHost; namespace WebApiConsoleApp { class Program { static void Main(string[] args) { var config = new HttpSelfHostConfiguration("http://localhost:8080"); config.Routes.MapHttpRoute( "API Default", "api/{controller}/{id}", new { id = RouteParameter.Optional }); using (HttpSelfHostServer server = new HttpSelfHostServer(config)) { server.OpenAsync().Wait(); Console.WriteLine("Press Enter to quit."); Console.ReadLine(); } } } }
サンプルアプリケーションの実行
最後にサンプルアプリケーションを実行する。Visual Studio 上から F5 を押下することで実行可能だが、冒頭で記載した通り 管理者権限 が必要な点に注意してほしい。アプリケーション起動後、Programs.cs 内に記載した URL である http://localhost:8080 にブラウザからアクセスすることで、以下のレスポンスを取得できる。
また、Visual Studio を管理者権限で実行しない場合、以下の例外が発生する。
System.AggregateException はハンドルされませんでした。 StackTrace: 場所 System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) 場所 System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken) 場所 System.Threading.Tasks.Task.Wait() 場所 WebApiConsoleApp.Program.Main(String[] args) 場所 c:\my_program\CSharp\WebApiConsoleApp\WebApiConsoleApp\Program.cs:行 19 場所 System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 場所 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 場所 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 場所 System.Threading.ThreadHelper.ThreadStart_Context(Object state) 場所 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 場所 System.Threading.ThreadHelper.ThreadStart() InnerException: System.ServiceModel.AddressAccessDeniedException HResult=-2146233087 Message=HTTP が URL http://+:8080/ を登録できませんでした。プロセスにこの名前空間へのアクセス権がありません (詳細については、http://go.microsoft.com/fwlink/?LinkId=70353 (英語ページの可能性があります) を参照してください)。