Azure Worker ロールで ASP.NET Web API 2 をホストする

作成者: Mike Wasson

このチュートリアルは、OWIN を使用して Web API フレームワークをセルフホストする Azure Worker ロールで ASP.NET Web API をホストする方法を示すものです。

Open Web Interface for .NET (OWIN) は、.NET Web サーバーと Web アプリケーションの間の抽象化を定義します。 OWIN はサーバーから Web アプリケーションを切り離します。そのため、OWIN は IIS 外部の (たとえば Azure worker ロール内の) 独自のプロセスで Web アプリケーションをセルフホストするのに最適です。

このチュートリアルでは、Microsoft.Owin.Host.HttpListener パッケージを使用します。これは、OWIN アプリケーションのセルフホストに使用される HTTP サーバーを提供します。

チュートリアルで使用するソフトウェアのバージョン

Microsoft Azure プロジェクトの作成

管理者特権で Visual Studio を起動します。 Azure Compute Emulator を使用してアプリケーションをローカルでデバッグするには、管理者特権が必要です。

[ファイル] メニューの [新規作成] をクリックし、[プロジェクト] をクリックします。 [インストールされているテンプレート] から、[Visual C#] の下の [クラウド] をクリックし、[Windows Azure クラウド サービス] をクリックします。 プロジェクトに "AzureApp" という名前を付け、[OK] をクリックします。

Screenshot of the 'new project' dialog box, highlighting the steps in the menu options to create an Azure App project.

[新しい Windows Azure クラウド サービス] ダイアログで、[Worker ロール] をダブルクリックします。 既定の名前 ("WorkerRole1") のままにします。 この手順では、ソリューションに worker ロールを追加します。 OK をクリックします。

Screenshot of the 'New Windows Azure Cloud Service' dialog box, showing the menu options to create a worker role.

作成される Visual Studio ソリューションには、次の 2 つのプロジェクトが含まれています。

  • "AzureApp" は、Azure アプリケーションのロールと構成を定義します。
  • "WorkerRole1" には、worker ロールのコードが含まれています。

一般に、Azure アプリケーションには複数のロールを含めることができますが、このチュートリアルでは 1 つのロールを使用します。

Screenshot of the solution explorer window, highlighting the new Azure App project and showing the app name and worker role option below it.

Web API と OWIN パッケージを追加する

[ツール] メニューで、[NuGet パッケージ マネージャー] をクリックし、[パッケージ マネージャー コンソール] をクリックします。

[パッケージ マネージャー コンソール] ウィンドウで、次のコマンドを入力します。

Install-Package Microsoft.AspNet.WebApi.OwinSelfHost

HTTP エンドポイントを追加する

ソリューション エクスプローラーで AzureApp プロジェクトを展開します。 [ロール] ノードを展開し、[WorkerRole1] を右クリックし、[プロパティ] を選択します。

Screenshot of the solution explorer window menu, highlighting the steps to select the worker role's property settings.

[エンドポイント] をクリックして、[エンドポイントの追加] をクリックします。

[プロトコル] ドロップダウン リストで、[http] を選択します。 [パブリック ポート][プライベート ポート] に「80」と入力します。 このポート番号は別の番号でもかまいません。 パブリック ポートは、クライアントがロールに要求を送信するときに使用します。

Screenshot of the protocol dropdown menu options that show the different service configurations and endpoint choices.

セルフホスト用に Web API を構成する

ソリューション エクスプローラーで、WorkerRole1 プロジェクトを右クリックし、[追加] / [クラス] を選択して新しいクラスを追加します。 クラスに Startup という名前を付けます。

Screenshot of the solution explorer window, showing the menu options and highlighting the path to adding a class.

このファイル内のすべての定型コードを次のように置き換えます。

using Owin;
using System.Web.Http;

namespace WorkerRole1
{
    class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            HttpConfiguration config = new HttpConfiguration();
            config.Routes.MapHttpRoute(
                "Default",
                "{controller}/{id}",
                new { id = RouteParameter.Optional });

            app.UseWebApi(config);
        }
    }
}

Web API コントローラーを追加する

次に、Web API コントローラー クラスを追加します。 WorkerRole1 プロジェクトを右クリックし、[追加] / [クラス] を選択します。 TestController クラスに名前を付けます。 このファイル内のすべての定型コードを次のように置き換えます。

using System;
using System.Net.Http;
using System.Web.Http;

namespace WorkerRole1
{
    public class TestController : ApiController
    {
        public HttpResponseMessage Get()
        {
            return new HttpResponseMessage()
            {
                Content = new StringContent("Hello from OWIN!")
            };
        }

        public HttpResponseMessage Get(int id)
        {
            string msg = String.Format("Hello from OWIN (id = {0})", id);
            return new HttpResponseMessage()
            {
                Content = new StringContent(msg)
            };
        }
    }
}

わかりやすくするために、このコントローラーはプレーンテキストを返す 2 つの GET メソッドを定義するだけにします。

OWIN ホストを起動する

WorkerRole.cs ファイルを開きます。 このクラスは、worker ロールが開始および停止されたときに実行されるコードを定義します。

次の using ステートメントを追加します。

using Microsoft.Owin.Hosting;

IDisposable メンバーを WorkerRole クラスに追加します。

public class WorkerRole : RoleEntryPoint
{
    private IDisposable _app = null;

    // ....
}

OnStart メソッドで、ホストを起動する次のコードを追加します。

public override bool OnStart()
{
    ServicePointManager.DefaultConnectionLimit = 12;

    // New code:
    var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Endpoint1"];
    string baseUri = String.Format("{0}://{1}", 
        endpoint.Protocol, endpoint.IPEndpoint);

    Trace.TraceInformation(String.Format("Starting OWIN at {0}", baseUri), 
        "Information");

    _app = WebApp.Start<Startup>(new StartOptions(url: baseUri));
    return base.OnStart();
}

WebApp.Start メソッドは OWIN ホストを起動します。 Startup クラスの名前は、メソッドの型パラメーターです。 慣例により、ホストはこのクラスの Configure メソッドを呼び出します。

OnStop をオーバーライドして、_app インスタンスを破棄します。

public override void OnStop()
{
    if (_app != null)
    {
        _app.Dispose();
    }
    base.OnStop();
}

WorkerRole.cs の完全なコードを次に示します。

using Microsoft.Owin.Hosting;
using Microsoft.WindowsAzure.ServiceRuntime;
using System;
using System.Diagnostics;
using System.Net;
using System.Threading;

namespace WorkerRole1
{
    public class WorkerRole : RoleEntryPoint
    {
        private IDisposable _app = null;

        public override void Run()
        {
            Trace.TraceInformation("WebApiRole entry point called", "Information");

            while (true)
            {
                Thread.Sleep(10000);
                Trace.TraceInformation("Working", "Information");
            }
        }

        public override bool OnStart()
        {
            ServicePointManager.DefaultConnectionLimit = 12;

            var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Endpoint1"];
            string baseUri = String.Format("{0}://{1}", 
                endpoint.Protocol, endpoint.IPEndpoint);

            Trace.TraceInformation(String.Format("Starting OWIN at {0}", baseUri), 
                "Information");

            _app = WebApp.Start<Startup>(new StartOptions(url: baseUri));
           return base.OnStart();
        }

        public override void OnStop()
        {
            if (_app != null)
            {
                _app.Dispose();
            }
            base.OnStop();
        }
    }
}

ソリューションをビルドし、F5 キーを押して Azure Compute Emulator でアプリケーションをローカルで実行します。 ファイアウォールの設定によっては、ファイアウォール経由でエミュレーターを許可することが必要になる場合があります。

Note

次のような例外が発生した場合は、このブログ記事で回避策を参照してください。 「ファイルまたはアセンブリ 'Microsoft.Owin, Version=2.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'、またはその依存関係の 1 つが読み込めませんでした。 指定したアセンブリのマニフェスト定義がアセンブリ参照と一致しません。 (HRESULT からの例外: 0x80131040)」

コンピューティング エミュレーターは、エンドポイントにローカル IP アドレスを割り当てます。 IP アドレスは、コンピューティング エミュレーター UI を表示することで確認できます。 タスク バーの通知領域でエミュレーター アイコンを右クリックし、[コンピューティング エミュレーター UI の表示] を選択します。

Screenshot of the Azure Compute Emulator U I, showing the menu and the I P endpoint address information, when selecting the 'service details' option.

[サービスのデプロイ]、デプロイ [id]、[サービスの詳細] で IP アドレスを見つけます。 Web ブラウザーを開き、http:// address/test/1 に移動します。ここで、address はコンピューティング エミュレーターによって割り当てられる IP アドレスであり、http://127.0.0.1:80/test/1 などです。 Web API コントローラーからの応答が表示されます。

Screenshot of the browser window showing the Web A P I controller response after inputting the I P address assigned by the compute emulator.

Azure に展開する

この手順では、Azure アカウントが必要です。 アカウントがない場合は、ほんの数分で無料評価版のアカウントを作成できます。 詳細については、「Microsoft Azure 無料評価版」を参照してください。

ソリューション エクスプローラーで、AzureApp プロジェクトを右クリックします。 公開を選択します。

Screenshot of the solution explorer window's menu options, which highlights the steps to follow in order to deploy or publish the project.

まだ Azure アカウントにサインインしていない場合は、[サインイン] をクリックします。

Screenshot of the 'publish Azure application' dialog box, which requests a sign in option before other options become available.

サインインしたら、サブスクリプションを選択し、[次へ] をクリックします。

Screenshot of the 'publish Azure application' after sign in, prompting user to choose a subscription type before continuing to the next step.

クラウド サービスの名前を入力し、リージョンを選択します。 Create をクリックしてください。

Screenshot of the 'create cloud service and storage account' dialog box, requesting user to enter a name and region for their application's service.

[発行] をクリックします。

Screenshot of the 'publish Azure application' window, confirming all of the settings selections made, and providing button options to go back or publish.

Azure クラウド サービス (クラシック) のカスタム ドメイン名の構成

その他のリソース