Hospedar ASP.NET Web API 2 em uma função de trabalho do Azure

por Mike Wasson

Este tutorial mostra como hospedar ASP.NET Web API em uma Função de Trabalho do Azure, usando o OWIN para hospedar automaticamente a estrutura da API Web.

Open Web Interface for .NET (OWIN) define uma abstração entre servidores Web .NET e aplicativos Web. O OWIN separa o aplicativo Web do servidor, o que torna o OWIN ideal para auto-hospedagem de um aplicativo Web em seu próprio processo, fora do IIS, por exemplo, dentro de uma função de trabalho do Azure.

Neste tutorial, você usará o pacote Microsoft.Owin.Host.HttpListener, que fornece um servidor HTTP que será usado para auto-hospedar aplicativos OWIN.

Versões de software usadas no tutorial

Criar um Projeto do Microsoft Azure

Inicie o Visual Studio com privilégios de administrador. Privilégios de administrador são necessários para depurar o aplicativo localmente, usando o Emulador de Computação do Azure.

No menu Arquivo , clique em Novo e em Projeto. Em Modelos Instalados, em Visual C#, clique em Nuvem e, em seguida, clique em Serviço de Nuvem do Windows Azure. Nomeie o projeto como "AzureApp" e clique em OK.

Captura de tela da caixa de diálogo

Na caixa de diálogo Novo Serviço de Nuvem do Windows Azure , clique duas vezes em Função de Trabalho. Deixe o nome padrão ("WorkerRole1"). Esta etapa adiciona uma função de trabalho à solução. Clique em OK.

Captura de tela da caixa de diálogo

A solução do Visual Studio criada contém dois projetos:

  • "AzureApp" define as funções e a configuração do aplicativo do Azure.
  • "WorkerRole1" contém o código para a função de trabalho.

Em geral, um aplicativo do Azure pode conter várias funções, embora este tutorial use uma única função.

Captura de tela da janela do gerenciador de soluções, realçando o novo projeto Azure App e mostrando o nome do aplicativo e a opção de função de trabalho abaixo dele.

Adicionar a API Web e os Pacotes OWIN

No menu Ferramentas , clique em Gerenciador de Pacotes NuGet e, em seguida, clique em Console do Gerenciador de Pacotes.

Na janela Console do Gerenciador de Pacotes, digite o seguinte comando:

Install-Package Microsoft.AspNet.WebApi.OwinSelfHost

Adicionar um ponto de extremidade HTTP

Em Gerenciador de Soluções, expanda o projeto do AzureApp. Expanda o nó Funções, clique com o botão direito do mouse em WorkerRole1 e selecione Propriedades.

Captura de tela do menu da janela do gerenciador de soluções, realçando as etapas para selecionar as configurações de propriedade da função de trabalho.

Clique em Pontos de Extremidade e clique em Adicionar Ponto de Extremidade.

Na lista suspensa Protocolo , selecione "http". Em Porta Pública e Porta Privada, digite 80. O número de porta pode ser diferente. A porta pública é o que os clientes usam quando enviam uma solicitação para a função.

Captura de tela das opções de menu suspenso do protocolo que mostram as diferentes configurações de serviço e opções de ponto de extremidade.

Configurar a API Web para Self-Host

Em Gerenciador de Soluções, clique com o botão direito do mouse no projeto WorkerRole1 e selecione Adicionar / Classe para adicionar uma nova classe. Nome da classe Startup.

Captura de tela da janela do gerenciador de soluções, mostrando as opções de menu e realçando o caminho para adicionar uma classe.

Substitua todo o código clichê neste arquivo pelo seguinte:

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);
        }
    }
}

Adicionar um controlador de API Web

Em seguida, adicione uma classe de controlador de API Web. Clique com o botão direito do mouse no projeto WorkerRole1 e selecione Adicionar / Classe. Nomeie a classe TestController. Substitua todo o código clichê neste arquivo pelo seguinte:

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)
            };
        }
    }
}

Para simplificar, esse controlador apenas define dois métodos GET que retornam texto sem formatação.

Iniciar o host OWIN

Abra o arquivo WorkerRole.cs. Essa classe define o código que é executado quando a função de trabalho é iniciada e interrompida.

Adicione a seguinte instrução usando:

using Microsoft.Owin.Hosting;

Adicione um membro IDisposable à WorkerRole classe :

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

    // ....
}

OnStart No método , adicione o seguinte código para iniciar o host:

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();
}

O método WebApp.Start inicia o host OWIN. O nome da Startup classe é um parâmetro de tipo para o método . Por convenção, o host chamará o Configure método dessa classe.

Substitua o OnStop para descartar a instância de _app :

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

Aqui está o código completo para 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();
        }
    }
}

Crie a solução e pressione F5 para executar o aplicativo localmente no Emulador de Computação do Azure. Dependendo das configurações de firewall, talvez seja necessário permitir o emulador por meio do firewall.

Observação

Se você receber uma exceção como a seguinte, consulte esta postagem no blog para obter uma solução alternativa. "Não foi possível carregar o arquivo ou assembly 'Microsoft.Owin, Version=2.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' ou uma de suas dependências. A definição de manifesto do assembly localizado não corresponde à referência do assembly. (Exceção de HRESULT: 0x80131040)"

O emulador de computação atribui um endereço IP local ao ponto de extremidade. Você pode encontrar o endereço IP exibindo a interface do usuário do Emulador de Computação. Clique com o botão direito do mouse no ícone do emulador na área de notificação da barra de tarefas e selecione Mostrar interface do usuário do Emulador de Computação.

Captura de tela da IU do Emulador de Computação do Azure, mostrando o menu e as informações de endereço do ponto de extremidade IP ao selecionar a opção

Localize o endereço IP em Implantações de Serviço, implantação [id], Detalhes do Serviço. Abra um navegador da Web e navegue até http:// address/test/1, em que o endereço é o endereço IP atribuído pelo emulador de computação; por exemplo, http://127.0.0.1:80/test/1. Você deve ver a resposta do controlador de API Web:

Captura de tela da janela do navegador mostrando a resposta do controlador web A P I depois de inserir o endereço IP atribuído pelo emulador de computação.

Implantar no Azure

Para esta etapa, você deve ter uma conta do Azure. Se você ainda não tiver uma, poderá criar uma conta de avaliação gratuita em apenas alguns minutos. Para obter detalhes, consulte Avaliação Gratuita do Microsoft Azure.

Em Gerenciador de Soluções, clique com o botão direito do mouse no projeto AzureApp. Selecione Publicar.

Captura de tela das opções de menu da janela do Gerenciador de Soluções, que realça as etapas a seguir para implantar ou publicar o projeto.

Se você não estiver conectado à sua conta do Azure, clique em Entrar.

Captura de tela da caixa de diálogo

Depois de entrar, escolha uma assinatura e clique em Avançar.

Captura de tela do 'aplicativo publicar do Azure' após a entrada, solicitando que o usuário escolha um tipo de assinatura antes de continuar para a próxima etapa.

Insira um nome para o serviço de nuvem e escolha uma região. Clique em Criar.

Captura de tela da caixa de diálogo

Clique em Publicar.

Captura de tela da janela

Configurando um nome de domínio personalizado para um serviço de nuvem do Azure (clássico)

Recursos adicionais