65.9K
CodeProject 正在变化。 阅读更多。
Home

创建和使用托管在 Azure 模拟器上的 Web API

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (2投票s)

2014年7月25日

CPOL

6分钟阅读

viewsIcon

22781

在本文中, 我们将了解如何使用托管在云 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 网格)。

谢谢

© . All rights reserved.