在 Azure 辅助角色中托管 ASP.NET Web API 2
作者:Mike Wasson
本教程介绍如何使用 OWIN 在 Azure 辅助角色中托管 ASP.NET Web API,以自承载 Web API 框架。
.NET (OWIN) .NET 开放 Web 接口定义 .NET Web 服务器和 Web 应用程序之间的抽象。 OWIN 将 Web 应用程序与服务器分离,这使得 OWIN 非常适合在自己的进程(IIS 外部)(例如,在 Azure 辅助角色内部)中自托管 Web 应用程序。
在本教程中,你将使用 Microsoft.Owin.Host.HttpListener 包,该包提供用于自承载 OWIN 应用程序的 HTTP 服务器。
本教程中使用的软件版本
- Visual Studio 2013
- Web API 2
- 用于 .NET 2.3 的 Azure SDK
创建 Microsoft Azure 项目
使用管理员权限启动 Visual Studio。 使用 Azure 计算模拟器在本地调试应用程序需要管理员权限。
在“ 文件 ”菜单上,单击“ 新建”,然后单击“ 项目”。 在 “已安装的模板”中,在“Visual C#”下,单击“ 云 ”,然后单击“ Windows Azure 云服务”。 将项目命名为“AzureApp”,然后单击“ 确定”。
在 “新建 Windows Azure 云服务 ”对话框中,双击“ 辅助角色”。 保留默认名称 (“WorkerRole1”) 。 此步骤将辅助角色添加到解决方案。 单击" 确定"。
创建的 Visual Studio 解决方案包含两个项目:
- “AzureApp”定义 Azure 应用程序的角色和配置。
- “WorkerRole1”包含辅助角色的代码。
通常,尽管本教程使用单个角色,但 Azure 应用程序可以包含多个角色。
添加 Web API 和 OWIN 包
在 “工具 ”菜单中,单击“ NuGet 包管理器”,然后单击“ 包管理器控制台”。
在“Package Manager Console”窗口中,输入以下命令:
Install-Package Microsoft.AspNet.WebApi.OwinSelfHost
添加 HTTP 终结点
在“解决方案资源管理器”中,展开“AzureApp”项目。 展开“角色”节点,右键单击“WorkerRole1”,然后选择“ 属性”。
单击“终结点”,然后单击“添加终结点”。
在 “协议 ”下拉列表中,选择“http”。 在 “公共端口 ”和 “专用端口”中,键入“80”。 这些端口号可以不同。 公共端口是客户端向角色发送请求时使用的内容。
为 Self-Host 配置 Web API
在“解决方案资源管理器”中,右键单击“WorkerRole1”项目,然后选择“添加 / 类”以添加新类。 命名类 Startup
。
将此文件中的所有样本代码替换为以下内容:
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)
};
}
}
}
为简单起见,此控制器只定义返回纯文本的两个 GET 方法。
启动 OWIN 主机
打开 WorkerRole.cs 文件。 此类定义启动和停止辅助角色时运行的代码。
添加以下 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 计算模拟器中本地运行应用程序。 根据防火墙设置,可能需要允许模拟器通过防火墙。
注意
如果遇到如下所示的异常,请参阅 此博客文章 了解解决方法。 “无法加载文件或程序集 'Microsoft.Owin, Version=2.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' 或其依赖项之一。 找到的程序集清单定义与程序集引用不匹配。 (HRESULT 的异常:0x80131040) ”
计算模拟器将本地 IP 地址分配给终结点。 可以通过查看计算模拟器 UI 来查找 IP 地址。 右键单击任务栏通知区域中的模拟器图标,然后选择“ 显示计算模拟器 UI”。
在“服务部署”、“部署 [id]”、“服务详细信息”下查找 IP 地址。 打开 Web 浏览器并导航到 http:// address/test/1,其中 address 是计算模拟器分配的 IP 地址;例如 , http://127.0.0.1:80/test/1
。 应会看到来自 Web API 控制器的响应:
部署到 Azure
对于此步骤,必须有一个 Azure 帐户。 如果没有帐户,只需几分钟即可创建一个免费试用帐户。 有关详细信息,请参阅 Microsoft Azure 免费试用版。
在“解决方案资源管理器”中,右键单击“AzureApp”项目。 选择“发布”。
如果未登录到 Azure 帐户,请单击“ 登录”。
登录后,选择订阅并单击“ 下一步”。
输入云服务的名称,然后选择一个区域。 单击“创建”。
单击“发布” 。