[Windows Azure][Web API] 部署 ASP.NET Web API Self-hosting 的服務到 Windows Azure 的注意事項

ASP.NET Web API Self-hosting 是一個很棒的服務掛載機制,它可以不用依賴 IIS 就能使用 Web API 的功能,簡單的說我們可以省下其他 IIS 的功能,直接運用 Web API 提供服務,可說是適合輕量化的 Web API 服務的選擇...

ASP.NET Web API Self-hosting 是一個很棒的服務掛載機制,它可以不用依賴 IIS 就能使用 Web API 的功能,簡單的說我們可以省下其他 IIS 的功能,直接運用 Web API 提供服務,可說是適合輕量化的 Web API 服務的選擇。

若是想要在 Windows Azure Platform 上使用 Self-hosting 的輕量化服務,最好的選擇就是 Worker Role,將所有的資源保留給 Web API Self-hosting 服務使用,不過 Web API Self-hosting 會自動要求修改系統的通訊埠,因為我們會使用這個指令來開放通訊埠:

this._hostingServer = new HttpSelfHostServer(this._hostingConfiguration);
this._hostingServer.Configuration.Formatters.Add(new MediaTypeFormatters.MultipartFormDataMediaTypeFormatter());

this._hostingServer.Configuration.Services.Replace(
    typeof(IHttpControllerSelector),
    new ServiceHostingHttpServiceSelector(this._hostingConfiguration));

this._hostingServer.OpenAsync().Wait();

當使用 OpenAsync() 時,會向作業系統要求取得通訊埠來聆聽,這時應用程式必須具有存取系統資訊的權限,若沒有存取系統權限的話,會在 OpenAsync() 時擲出 System.AggregateException,在 Windows Azure 上則會造成 Role Recycle 的狀態,導致部署失敗。

要避免這個問題,請在 ServiceDefinition.csdef 中手動加入提升權限的指令:

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="..." xmlns="..." schemaVersion="2012-10.1.8">
  <WorkerRole name="..." vmsize="ExtraSmall">
    <Runtime executionContext="elevated" />
    ...
  </WorkerRole>
</ServiceDefinition>

這樣就可以在 Worker Role 上順利執行 Web API Self-hosting 的掛載程序了。

另外,請注意要在服務設定中開放 HTTP Port 80 (或是 self-hosting 時要用到的通訊埠),否則就算掛載成功了,外界可能也無法存取。

Reference:

http://stackoverflow.com/questions/11239890/asp-net-webapi-selfhost-service-fails-on-http-url-registration