Freigeben über


Hosten ASP.NET Web-API 2 in einer Azure-Workerrolle

von Mike Wasson

In diesem Lernprogramm wird gezeigt, wie Sie ASP.NET Web-API in einer Azure-Workerrolle hosten, indem Sie OWIN verwenden, um das Web-API-Framework selbst zu hosten.

Open Web Interface for .NET (OWIN) definiert eine Abstraktion zwischen .NET-Webservern und Webanwendungen. OWIN entkoppelt die Webanwendung vom Server, wodurch OWIN ideal für das Selbsthosting einer Webanwendung in Ihrem eigenen Prozess, z. B. außerhalb von IIS, innerhalb einer Azure-Workerrolle geeignet ist.

In diesem Lernprogramm verwenden Sie das Microsoft.Owin.Host.HttpListener-Paket, das einen HTTP-Server bereitstellt, der zum Selbsthosting von OWIN-Anwendungen verwendet wird.

Im Lernprogramm verwendete Softwareversionen

Erstellen eines Microsoft Azure-Projekts

Starten Sie Visual Studio mit Administratorrechten. Administratorrechte werden benötigt, um die Anwendung lokal mithilfe des Azure Compute Emulators zu debuggen.

Klicken Sie im Menü "Datei" auf "Neu", und klicken Sie dann auf "Projekt". Klicken Sie unter Visual C# unter "Installierte Vorlagen" auf "Cloud ", und klicken Sie dann auf "Windows Azure Cloud Service". Benennen Sie das Projekt "AzureApp", und klicken Sie auf "OK".

Screenshot des Dialogfelds

Doppelklicken Sie im Dialogfeld New Windows Azure Cloud Service auf Worker Role. Behalten Sie den Standardnamen ("WorkerRole1") bei. In diesem Schritt wird der Lösung eine Worker-Rolle hinzugefügt. Klicke auf OK.

Screenshot des Dialogfelds

Die Visual Studio-Projektmappe, die erstellt wird, enthält zwei Projekte:

  • "AzureApp" definiert die Rollen und Konfigurationen für die Azure-Anwendung.
  • "WorkerRole1" enthält den Code für die Worker-Role.

Im Allgemeinen kann eine Azure-Anwendung mehrere Rollen enthalten, obwohl in diesem Lernprogramm eine einzelne Rolle verwendet wird.

Screenshot des Fensters

Hinzufügen der Web-API und OWIN-Pakete

Klicken Sie im Menü "Extras " auf "NuGet-Paket-Manager", und klicken Sie dann auf "Paket-Manager-Konsole".

Geben Sie im Paket-Manager-Konsolenfenster den folgenden Befehl ein:

Install-Package Microsoft.AspNet.WebApi.OwinSelfHost

Hinzufügen eines HTTP-Endpunkts

Erweitern Sie im Projektmappen-Explorer das AzureApp-Projekt. Erweitern Sie den Knoten "Rollen", klicken Sie mit der rechten Maustaste auf "WorkerRole1", und wählen Sie "Eigenschaften" aus.

Screenshot des Fenstermenüs

Klicken Sie auf Endpunkte, und klicken Sie dann auf "Endpunkt hinzufügen".

Wählen Sie in der Dropdownliste "Protokoll " die Option "http" aus. Geben Sie in "Öffentlicher Port " und "Privater Port" den Typ 80 ein. Diese Portnummern können unterschiedlich sein. Der öffentliche Port wird von Clients verwendet, wenn sie eine Anfrage an die Rolle senden.

Screenshot der Menüoptionen für das Protokolldropdown, in denen die verschiedenen Dienstkonfigurationen und Endpunktoptionen angezeigt werden.

Konfigurieren der Web-API für Self-Host

Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das WorkerRole1-Projekt, und wählen Sie "Klasse / " aus, um eine neue Klasse hinzuzufügen. Benennen Sie die Klasse Startup.

Screenshot des Projektmappen-Explorer-Fensters mit den Menüoptionen und Hervorheben des Pfads zum Hinzufügen einer Klasse.

Ersetzen Sie den gesamten Codebaustein in dieser Datei durch Folgendes:

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

Hinzufügen eines Web-API-Controllers

Fügen Sie als Nächstes eine Web-API-Controllerklasse hinzu. Klicken Sie mit der rechten Maustaste auf das WorkerRole1-Projekt, und wählen Sie "Klasse / aus. Nennen Sie die Klasse TestController. Ersetzen Sie den gesamten Codebaustein in dieser Datei durch Folgendes:

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

Aus Gründen der Einfachheit definiert dieser Controller nur zwei GET-Methoden, die Nur-Text zurückgeben.

Starten des OWIN-Hosts

Öffnen Sie die datei WorkerRole.cs. Diese Klasse definiert den Code, der ausgeführt wird, wenn die Workerrolle gestartet und beendet wird.

Fügen Sie die folgende using-Anweisung hinzu:

using Microsoft.Owin.Hosting;

Fügen Sie der IDisposable-Mitglied zur WorkerRole Klasse hinzu:

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

    // ....
}

Fügen Sie in der OnStart Methode den folgenden Code hinzu, um den Host zu starten:

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

Die WebApp.Start-Methode startet den OWIN-Host. Der Name der Startup Klasse ist ein Typparameter für die Methode. Standardmäßig ruft der Host die Configure Methode dieser Klasse auf.

Überschreiben Sie OnStop, um die Instanz _app zu löschen.

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

Hier ist der vollständige Code für 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();
        }
    }
}

Erstellen Sie die Lösung, und drücken Sie F5, um die Anwendung lokal im Azure Compute Emulator auszuführen. Je nach Firewalleinstellungen müssen Sie den Emulator möglicherweise über Ihre Firewall zulassen.

Hinweis

Wenn Sie eine Ausnahme wie die folgende erhalten, finden Sie in diesem Blogbeitrag eine Problemumgehung. "Datei oder Assembly 'Microsoft.Owin, Version=2.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' oder eine ihrer Abhängigkeiten konnte nicht geladen werden. Die gefundene Manifestdefinition der Assembly stimmt nicht mit dem Assemblyverweis überein. (Ausnahme von HRESULT: 0x80131040)"

Der Computeemulator weist dem Endpunkt eine lokale IP-Adresse zu. Sie finden die IP-Adresse, indem Sie die Compute-Emulator-Benutzeroberfläche anzeigen. Klicken Sie im Infobereich der Taskleiste mit der rechten Maustaste auf das Emulatorsymbol, und wählen Sie " Compute-Emulator-UI anzeigen" aus.

Screenshot des Azure Compute Emulator U I mit dem Menü und den I P-Endpunktadresseninformationen, wenn Sie die Option

Suchen Sie die IP-Adresse unter Dienstbereitstellungen, Bereitstellung [id], Dienstdetails. Öffnen Sie einen Webbrowser, und navigieren Sie zu http:// adresse/test/1, wobei die Adresse die IP-Adresse ist, die vom Computeemulator zugewiesen wird; beispiel: http://127.0.0.1:80/test/1. Die Antwort des Web-API-Controllers sollte angezeigt werden:

Screenshot des Browserfensters mit der Antwort des Web A P I-Controllers nach eingabe der vom Computeemulator zugewiesenen I P-Adresse.

In Azure bereitstellen

Für diesen Schritt müssen Sie über ein Azure-Konto verfügen. Wenn Sie noch kein Konto haben, können Sie in nur wenigen Minuten ein kostenloses Testkonto erstellen. Ausführliche Informationen finden Sie in der kostenlosen Testversion von Microsoft Azure.

Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das AzureApp-Projekt. Klicken Sie auf Veröffentlichen.

Screenshot der Menüoptionen des Projektmappen-Explorers, in denen die schritte zum Bereitstellen oder Veröffentlichen des Projekts hervorgehoben werden.

Wenn Sie nicht bei Ihrem Azure-Konto angemeldet sind, klicken Sie auf "Anmelden".

Screenshot des Dialogfelds

Nachdem Sie angemeldet sind, wählen Sie ein Abonnement aus, und klicken Sie auf "Weiter".

Screenshot der Option

Geben Sie einen Namen für den Clouddienst ein, und wählen Sie eine Region aus. Klicke auf Erstellen.

Screenshot des Dialogfelds

Klicken Sie auf Veröffentlichen.

Screenshot des Fensters

Konfigurieren eines benutzerdefinierten Domänennamens für einen Azure-Clouddienst (klassisch)

Zusätzliche Ressourcen