创建和使用托管在 Azure 模拟器上的 Web API
在本文中,
引言
经过深入思考,我决定写我的第一篇文章!:)。在这篇文章中,我们将了解如何在 Azure 工作器角色中创建 web api 服务,并使用 OWIN/Katana 进程将其自托管。然后,我们将消耗该服务并将其绑定到 KendoGrid。对我来说,这是一篇很长的文章,因为这是我的第一篇,如果您能提供评论、建议或提出任何问题,我将非常高兴。
先决条件
您应该了解 Web API 和 Kendo Grid。如果您不了解,请参阅以下内容。
http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api
http://demos.telerik.com/kendo-ui/grid/api
概述
Open Web Interface for .NET (OWIN) 定义了 .NET Web 服务器和 Web 应用程序之间的抽象。OWIN 将 Web 应用程序与服务器解耦,这使得 OWIN 非常适合在您自己的进程中(例如,在 Azure 工作器角色内部)自托管 Web 应用程序,而不是在 IIS 中。(来自 MSDN 的定义)。
首先,让我们开始在 Azure 工作器进程中创建 web api。
要创建它,我们应该拥有 Microsoft Visual Studio 2013 和 Windows Azure SDK 工具包。
您可以在此处下载 SDK。
让我们潜入大海吧 :).
创建 Azure 项目。
注意:要创建/运行 Azure 项目,我们需要以管理员模式运行 Visual Studio。
在 文件 菜单中,单击 新建,然后单击 项目。在 已安装模板下,在 Visual C# 下,单击 云,然后单击 Windows Azure Cloud Service。将项目命名为“AzureApp”,然后单击 确定。
为项目命名,在本例中是“MyFirstAzureApp”。在 “新建 Windows Azure Cloud Service”对话框中,双击 工作器角色。此步骤将一个工作器角色添加到解决方案。单击 确定。 请勿更改工作器角色的名称(保持为“WorkerRole1”)。
现在 Azure 项目已准备就绪。该解决方案文件包含两个项目:
1. MyFirstAzureApp
2. WorkerRole1
MyFirstAzureApp 包含角色(WorkerRole1)以及 Azure 应用程序设置所需的配置。
WorkerRole1 包含在 MyFirstAzureApp 的角色中执行的业务逻辑(在本例中为 webapi 方法)。
我们可以使用 WebRole 或 WorkerRole。创建和部署应用程序到云时,会考虑 WebRole。它提供了一个 Internet Information Services (IIS) Web 服务器,用于托管应用程序。WorkerRole 用于我们希望作为后台进程执行的进程。
在本例中,我们只使用 Web API(不将其视为 Web 应用程序),因此我选择了 WorkerRole。
添加和配置终结点。
现在是时候配置 Azure 服务的终结点了。双击 MyFirstAzureApp -> Roles 下的 WorkerRole1。选择“终结点”部分。现在我们可以添加终结点了。单击“添加终结点”,您可以编辑预定义的终结点。(在本例中,我们不修改终结点名称)。从“协议”中选择 HTTP 端口,并将公共端口和私有端口值都设置为 80,然后保存。
添加 Controller
现在添加一个 Web API 控制器。右键单击 WorkerRole1 项目 -> 添加 -> 类。将其命名为 FirstController。
添加一个 GET Web 方法。
public JToken Get() { JToken json = JObject.Parse("{ \"firstName\": \"John\", \"lastName\": \"Smith\", \"isAlive\": true, \"age\": 25, \"height_cm\": 167.6, \"address\": { \"streetAddress\": \"21 2nd Street\", \"city\": \"New York\", \"state\": \"NY\", \"postalCode\": \"10021-3100\" }, \"phoneNumbers\": [ { \"type\": \"home\", \"number\": \"212 555-1234\" }, { \"type\": \"office\", \"number\": \"646 555-4567\" } ]}"); return json; }
确保添加命名空间“using Newtonsoft.Json.Linq;”
配置 Web API。
现在我们需要配置我们的 Web API,以便自托管它。在控制器所在的同一位置添加另一个类,并将其命名为 StartUp。
用以下代码替换所有现有代码。
using Owin; using System.Web.Http; namespace WorkerRole1 { class Startup { public void Configuration(IAppBuilder app) { HttpConfiguration config = new HttpConfiguration(); config.Routes.MapHttpRoute( "Default", "api/{controller}/{id}", new { id = RouteParameter.Optional }); app.UseWebApi(config); } } }
现在您会发现许多关于 Owin 的命名空间和配置的错误。现在是时候添加关于 OWIN 自托管的 nuget 引用了。
转到 nuget 控制台管理器并安装以下 nuget 包。
Install-Package Microsoft.AspNet.WebApi.OwinSelfHost
现在我们需要配置我们的工作器角色进程以自托管我们的 web api。
在 WorkerRole1 项目中,在“WorkerRole.cs”文件中添加“using Microsoft.Owin.Hosting;”
另外,添加“private IDisposable _app = null;”
public class WorkerRole : RoleEntryPoint { private IDisposable _app = null; // .... }
在 OnStart() 方法中添加以下代码
var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Endpoint1"]; string baseUri = String.Format("{0}://{1}", endpoint.Protocol, endpoint.IPEndpoint); _app = WebApp.Start<Startup>(new StartOptions(url: baseUri));
最后,该方法如下所示。
public override bool OnStart() { // Set the maximum number of concurrent connections ServicePointManager.DefaultConnectionLimit = 12; // For information on handling configuration changes // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357. var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Endpoint1"]; string baseUri = String.Format("{0}://{1}", endpoint.Protocol, endpoint.IPEndpoint); _app = WebApp.Start<Startup>(new StartOptions(url: baseUri)); return base.OnStart(); }
我们已经准备好运行 Azure 应用程序了。构建解决方案,确保没有错误。运行应用程序。
运行应用程序后,我们会在任务栏上看到一个模拟器。右键单击模拟器 -> 显示计算模拟器 UI。在其中,选择“服务详细信息”。
注意:出于某些技术原因,我没有将我的应用程序发布到 Azure。我将使用此模拟器作为托管地址并继续。请不要介意。
现在我们可以使用这个自托管的 web api 了。在浏览器中执行 URL“http://127.0.0.1/api/First”。
您将获得类似以下的 JSON 数据。
好吧,还没完成!:).
我们可以在这个项目本身中创建我们的 Web 项目并在那里消耗 webapi。但是,在部署服务后,另一个团队想要消耗相同的服务时,就会出现访问问题。
这里我称之为“跨域请求”的问题。
为了处理这个问题,我正在使我的应用程序支持跨域访问。
启用跨域。
让我们为应用程序启用 CORS。为此,请停止模拟器并停止应用程序。
转到控制台管理器并安装以下 nuget 包。
Install-Package Microsoft.AspNet.WebApi.Cors
您会发现引用文件已添加到您的 workerrole1 项目中。
添加以下命名空间并为服务配置 EnableCors。添加后,代码如下所示。
using Owin; using System.Web.Http; using System.Web.Http.Cors; namespace WorkerRole1 { class Startup { public void Configuration(IAppBuilder app) { HttpConfiguration config = new HttpConfiguration(); var cors = new EnableCorsAttribute("https://:51300", "*", "*"); config.EnableCors(cors); config.Routes.MapHttpRoute( "Default", "api/{controller}/{id}", new { id = RouteParameter.Optional }); app.UseWebApi(config); } } }
注意:这里我的客户端应用程序将在 localhost 上工作(https://:51300)。如果您想启用所有域的 CORS,可以将 localhost URL 替换为“*”。
构建站点并运行它。现在它已准备好进行跨域访问。
这就是在 Azure 环境中创建自托管 Web API 的全部内容。
在 Kendogrid 中消耗服务。
如果您看到这里,我想我们应该知道 Kendogird,如果不知道,请使用上面的 URL 查看。
创建一个空的 Web 应用程序并添加一个页面。
启动 Visual Studio -> 新建项目 -> 模板 -> Visual C# -> Web -> 选择 Asp.Net Web 应用程序。
随意命名您的应用程序。
选择“空”模板。
项目打开后,添加一个 Web 窗体并随意命名(在本例中为 Default.aspx)。
窗体已准备好,我们需要创建一个 kendo 网格并消耗我们的服务。
现在为了使用 kendo 网格,我们需要下载一系列脚本和样式文件。请下载这些文件,或者您可以添加在线引用,如下所示(最好是下载文件)。
<base href="http://demos.telerik.com/kendo-ui/grid/api"> <style> html { font-size: 12px; font-family: Arial, Helvetica, sans-serif; } </style> <title></title> <link href="http://cdn.kendostatic.com/2014.2.716/styles/kendo.common.min.css" rel="stylesheet" /> <link href="http://cdn.kendostatic.com/2014.2.716/styles/kendo.default.min.css" rel="stylesheet" /> <link href="http://cdn.kendostatic.com/2014.2.716/styles/kendo.dataviz.min.css" rel="stylesheet" /> <link href="http://cdn.kendostatic.com/2014.2.716/styles/kendo.dataviz.default.min.css" rel="stylesheet" /> <script src="http://cdn.kendostatic.com/2014.2.716/js/jquery.min.js"></script> <script src="http://cdn.kendostatic.com/2014.2.716/js/angular.min.js"></script> <script src="http://cdn.kendostatic.com/2014.2.716/js/kendo.all.min.js"></script>
在 form 标签内添加一个空的 div。我们将把网格绑定到这个 div。
在 ready 函数中编写 jQuery 来绑定 kendogrid。(这里我显示了整个页面)
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.Default" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <base href="http://demos.telerik.com/kendo-ui/grid/api"> <style> html { font-size: 12px; font-family: Arial, Helvetica, sans-serif; } </style> <title></title> <link href="http://cdn.kendostatic.com/2014.2.716/styles/kendo.common.min.css" rel="stylesheet" /> <link href="http://cdn.kendostatic.com/2014.2.716/styles/kendo.default.min.css" rel="stylesheet" /> <link href="http://cdn.kendostatic.com/2014.2.716/styles/kendo.dataviz.min.css" rel="stylesheet" /> <link href="http://cdn.kendostatic.com/2014.2.716/styles/kendo.dataviz.default.min.css" rel="stylesheet" /> <script src="http://cdn.kendostatic.com/2014.2.716/js/jquery.min.js"></script> <script src="http://cdn.kendostatic.com/2014.2.716/js/angular.min.js"></script> <script src="http://cdn.kendostatic.com/2014.2.716/js/kendo.all.min.js"></script> </head> <body> <script> $(document).ready(function () { $("#divId").kendoGrid({ dataSource: { transport: { read: "http://127.0.0.1/api/First", }, schema: { model: { fields: { firstName: { type: "string" } } } } }, height: 500, scrollable: true, selectable: true, columns: [ { field: "firstName", title:"First Name" }, { field: "lastName", title: "Last Name" }, { field: "isAlive", title: "Alive" }, { field: "age", title: "Age" }, { field: "address.streetAddress", title: "Street Address" } , { field: "address.city", title: "City" } , { field: "address.state", title: "State" } , { field: "address.postalCode", title: "Postal Code" } , { field: "phoneNumbers[0].number", title: "Home Phone" } , { field: "phoneNumbers[1].number", title: "Office Phone" } ] }); }); </script> <form id="form1" runat="server"> <div> <div id="divId"> </div> </div> </form> </body> </html>
现在一切都准备就绪。只需运行应用程序,您就会看到奇迹。
正如我们在服务中只使用了一个 JSON 记录一样,如果我们使用多条记录,我们就能感受到 kendo 网格的美妙之处(这里我们主要关注 kendo 网格)。
谢谢