Host ASP.NET-Web-API 2 in einer Azure-Workerrolle
von Mike Wasson
In diesem Tutorial erfahren Sie, 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. Dadurch eignet sich OWIN ideal für das Selbsthosting einer Webanwendung in Ihrem eigenen Prozess, außerhalb von IIS, z. B. innerhalb einer Azure-Workerrolle.
In diesem Tutorial verwenden Sie das Paket Microsoft.Owin.Host.HttpListener, das einen HTTP-Server bereitstellt, der zum Selbsthosten von OWIN-Anwendungen verwendet wird.
Im Tutorial verwendete Softwareversionen
- Visual Studio 2013
- Web-API 2
- Azure SDK für .NET 2.3
Erstellen eines Microsoft Azure-Projekts
Starten Sie Visual Studio mit Administratorrechten. Administratorrechte sind erforderlich, um die Anwendung mithilfe des Azure-Computeemulators lokal zu debuggen.
Klicken Sie im Menü Datei auf Neu und dann auf Projekt. Klicken Sie unter Installierte Vorlagen unter Visual C# auf Cloud und dann auf Windows Azure Cloud Service. Nennen Sie das Projekt "AzureApp", und klicken Sie auf OK.
Doppelklicken Sie im Dialogfeld Neuer Windows Azure-Clouddienst auf Workerrolle. Behalten Sie den Standardnamen ("WorkerRole1") bei. In diesem Schritt wird der Lösung eine Workerrolle hinzugefügt. Klicken Sie auf OK.
Die erstellte Visual Studio-Projektmappe enthält zwei Projekte:
- "AzureApp" definiert die Rollen und die Konfiguration für die Azure-Anwendung.
- "WorkerRole1" enthält den Code für die Workerrolle.
Im Allgemeinen kann eine Azure-Anwendung mehrere Rollen enthalten, obwohl in diesem Tutorial eine einzelne Rolle verwendet wird.
Hinzufügen der Web-API und der OWIN-Pakete
Klicken Sie im Menü Extras auf NuGet-Paket-Manager und dann auf Paket-Manager-Konsole.
Geben Sie im Fenster Paket-Manager-Konsole den folgenden Befehl ein:
Install-Package Microsoft.AspNet.WebApi.OwinSelfHost
Hinzufügen eines HTTP-Endpunkts
Erweitern Sie in Projektmappen-Explorer das Projekt AzureApp. Erweitern Sie den Knoten Rollen, klicken Sie mit der rechten Maustaste auf WorkerRole1, und wählen Sie Eigenschaften aus.
Klicken Sie auf Endpunkte und dann auf Endpunkt hinzufügen.
Wählen Sie in der Dropdownliste Protokoll die Option "http" aus. Geben Sie unter Öffentlicher Port und privater Port den Wert 80 ein. Diese Portnummern dürfen sich unterscheiden. Der öffentliche Port wird von Clients verwendet, wenn sie eine Anforderung an die Rolle senden.
Konfigurieren der Web-API für Self-Host
Klicken Sie in Projektmappen-Explorer mit der rechten Maustaste auf das Projekt WorkerRole1, und wählen SieKlassehinzufügen / aus, um eine neue Klasse hinzuzufügen. Geben Sie der Klassen den Namen Startup
.
Ersetzen Sie den gesamten Code der Bausteine 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 Projekt WorkerRole1, und wählen SieKlassehinzufügen / aus. Nennen Sie die Klasse TestController. Ersetzen Sie den gesamten Code der Bausteine 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)
};
}
}
}
Der Einfachheit halber 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 WorkerRole
-Klasse ein IDisposable-Element 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. Gemäß Konvention ruft der Host die Configure
-Methode dieser Klasse auf.
Überschreiben Sie, um die OnStop
_app instance zu verwerfen:
public override void OnStop()
{
if (_app != null)
{
_app.Dispose();
}
base.OnStop();
}
Hier sehen Sie den vollständigen 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-Computeemulator auszuführen. Abhängig von Ihren Firewalleinstellungen müssen Sie möglicherweise den Emulator ü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 Manifestdefinition der befindeten Assembly stimmt nicht mit dem Assemblyverweis überein. (Ausnahme von HRESULT: 0x80131040)"
Der Computeemulator weist dem Endpunkt eine lokale IP-Adresse zu. Sie können die IP-Adresse finden, indem Sie die Benutzeroberfläche des Computeemulators anzeigen. Klicken Sie im Infobereich der Taskleiste mit der rechten Maustaste auf das Emulatorsymbol, und wählen Sie Computeemulator-Benutzeroberfläche anzeigen aus.
Suchen Sie die IP-Adresse unter Dienstbereitstellungen, Bereitstellung [ID], Dienstdetails. Öffnen Sie einen Webbrowser, und navigieren Sie zu http:// adresse/test/1, wobei adresse die vom Computeemulator zugewiesene IP-Adresse ist. beispiel: http://127.0.0.1:80/test/1
. Die Antwort des Web-API-Controllers sollte angezeigt werden:
In Azure bereitstellen
Für diesen Schritt benötigen Sie ein Azure-Konto. Wenn Sie noch nicht über ein Konto verfügen, können Sie in wenigen Minuten ein kostenloses Testkonto erstellen. Weitere Informationen finden Sie unter Kostenlose Microsoft Azure-Testversion.
Klicken Sie in Projektmappen-Explorer mit der rechten Maustaste auf das Projekt AzureApp. Wählen Sie Veröffentlichen aus.
Wenn Sie nicht bei Ihrem Azure-Konto angemeldet sind, klicken Sie auf Anmelden.
Nachdem Sie angemeldet sind, wählen Sie ein Abonnement aus, und klicken Sie auf Weiter.
Geben Sie einen Namen für den Clouddienst ein, und wählen Sie eine Region aus. Klicken Sie auf Erstellen.
Klicken Sie auf Veröffentlichen.
Konfigurieren eines benutzerdefinierten Domänennamens für einen Azure-Clouddienst (klassisch)