Open Web Interface for .NET (OWIN) mit ASP.NET Core
Von Steve Smith und Rick Anderson
ASP.NET Core:
- unterstützt Open Web Interface for .NET (OWIN)
- enthält mit .NET Core kompatiblen Ersatz für
Microsoft.Owin.*
-Bibliotheken (Katana)
Mit OWIN können Web-Apps von Webservern entkoppelt werden. OWIN legt eine Standardmöglichkeit des Einsatzes von Middleware in einer Pipeline zum Verarbeiten von Anforderungen und den entsprechenden Antworten fest. ASP.NET Core-Anwendungen und -Middleware können mit auf OWIN basierten Anwendungen, Servern und OWIN basierter Middleware zusammenarbeiten.
OWIN bietet eine Entkopplungsebene, die das gemeinsame Verwenden zweier Frameworks mit unterschiedlichen Objektmodellen zulässt. Das Microsoft.AspNetCore.Owin
-Paket bietet zwei Adapterimplementierungen:
- ASP.NET Core auf OWIN
- OWIN auf ASP.NET Core
So kann ASP.NET Core auf einem mit OWIN kompatiblen Server bzw. Host gehostet werden. Alternativ können andere mit OWIN kompatible Komponenten über ASP.NET Core ausgeführt werden.
Hinweis
Das Verwenden dieser Adapter führt zu Leistungseinbußen. Apps, die nur ASP.NET Core-Komponenten verwenden, sollten keine Microsoft.AspNetCore.Owin
-Pakete oder Adapter verwenden.
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Ausführen von OWIN-Middleware in der ASP.NET Core-Pipeline
Die OWIN-Unterstützung von ASP.NET Core wird im Rahmen des Microsoft.AspNetCore.Owin
-Pakets bereitgestellt. Sie können OWIN-Unterstützung in Ihrem Projekt ermöglichen, indem Sie dieses Paket installieren.
OWIN-Middleware stimmt mit der OWIN-Spezifikation überein, die eine Func<IDictionary<string, object>, Task>
-Schnittstelle und das Festlegen spezifischer Schlüssel erfordert (wie z.B. owin.ResponseBody
). Die folgende einfache OWIN-Middleware zeigt „Hello World“ (Hallo Welt) an:
public Task OwinHello(IDictionary<string, object> environment)
{
string responseText = "Hello World via OWIN";
byte[] responseBytes = Encoding.UTF8.GetBytes(responseText);
// OWIN Environment Keys: https://owin.org/spec/spec/owin-1.0.0.html
var responseStream = (Stream)environment["owin.ResponseBody"];
var responseHeaders = (IDictionary<string, string[]>)environment["owin.ResponseHeaders"];
responseHeaders["Content-Length"] = new string[] { responseBytes.Length.ToString(CultureInfo.InvariantCulture) };
responseHeaders["Content-Type"] = new string[] { "text/plain" };
return responseStream.WriteAsync(responseBytes, 0, responseBytes.Length);
}
Die Beispielsignatur gibt ein Task
-Objekt zurück und akzeptiert ein IDictionary<string, object>
, wie OWIN es erfordert.
Der folgende Code veranschaulicht, wie Sie die OwinHello
-Middleware (siehe oben) der ASP.NET Core-Pipeline mit der UseOwin
-Erweiterungsmethode hinzufügen.
public void Configure(IApplicationBuilder app)
{
app.UseOwin(pipeline =>
{
pipeline(next => OwinHello);
});
}
Sie können andere Aktionen konfigurieren, die in der OWIN-Pipeline durchgeführt werden sollen.
Hinweis
Antwortheader sollten nur vor dem ersten Schreiben in den Antwortstream modifiziert werden.
Hinweis
Mehrere Aufrufe von UseOwin
werden aus Leistungsgründen nicht empfohlen. OWIN-Komponenten funktionieren am besten, wenn sie gruppiert werden.
app.UseOwin(pipeline =>
{
pipeline(next =>
{
return async environment =>
{
// Do something before.
await next(environment);
// Do something after.
};
});
});
Ausführen von ASP.NET Core auf einem auf OWIN basierten Server und Nutzen der WebSockets-Unterstützung
Der Zugriff auf Features wie WebSockets ist ein weiteres Beispiel dafür, wie ASP.NET Core Features von auf OWIN basierten Servern nutzen kann. Der .NET OWIN-Webserver, der im vorherigen Beispiel verwendet wurde, verfügt über integrierte Unterstützung für WebSockets. Dies kann von einer ASP.NET Core-Anwendung genutzt werden. Das unten stehende Beispiel zeigt eine einfache Web-App, die WebSockets unterstützt und alles zurückgibt, was über WebSockets an den Server gesendet wurde.
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.Use(async (context, next) =>
{
if (context.WebSockets.IsWebSocketRequest)
{
WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();
await EchoWebSocket(webSocket);
}
else
{
await next();
}
});
app.Run(context =>
{
return context.Response.WriteAsync("Hello World");
});
}
private async Task EchoWebSocket(WebSocket webSocket)
{
byte[] buffer = new byte[1024];
WebSocketReceiveResult received = await webSocket.ReceiveAsync(
new ArraySegment<byte>(buffer), CancellationToken.None);
while (!webSocket.CloseStatus.HasValue)
{
// Echo anything we receive
await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, received.Count),
received.MessageType, received.EndOfMessage, CancellationToken.None);
received = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer),
CancellationToken.None);
}
await webSocket.CloseAsync(webSocket.CloseStatus.Value,
webSocket.CloseStatusDescription, CancellationToken.None);
}
}
OWIN-Umgebung
Sie können mit HttpContext
eine OWIN-Umgebung erstellen.
var environment = new OwinEnvironment(HttpContext);
var features = new OwinFeatureCollection(environment);
OWIN-Schlüssel
OWIN ist von einem IDictionary<string,object>
-Objekt abhängig, um Informationen innerhalb eines Austauschs einer HTTP-Anforderung und einer Antwort weiterzugeben. ASP.NET Core implementiert die unten aufgelisteten Schlüssel. Weitere Informationen finden Sie in den Hauptspezifikationen und Erweiterungen und in den OWIN Key Guidelines and Common Keys (Wichtigste Richtlinien und gängige Schlüsse von OWIN).
Anforderungsdaten (OWIN v1.0.0)
Key | Wert (Typ) | Beschreibung |
---|---|---|
owin.RequestScheme | String |
|
owin.RequestMethod | String |
|
owin.RequestPathBase | String |
|
owin.RequestPath | String |
|
owin.RequestQueryString | String |
|
owin.RequestProtocol | String |
|
owin.RequestHeaders | IDictionary<string,string[]> |
|
owin.RequestBody | Stream |
Anforderungsdaten (OWIN v1.1.0)
Key | Wert (Typ) | Beschreibung |
---|---|---|
owin.RequestId | String |
Optional |
Antwortdaten (OWIN v1.0.0)
Key | Wert (Typ) | Beschreibung |
---|---|---|
owin.ResponseStatusCode | int |
Optional |
owin.ResponseReasonPhrase | String |
Optional |
owin.ResponseHeaders | IDictionary<string,string[]> |
|
owin.ResponseBody | Stream |
Andere Daten (OWIN v1.0.0)
Key | Wert (Typ) | Beschreibung |
---|---|---|
owin.CallCancelled | CancellationToken |
|
owin.Version | String |
Gängige Schlüssel
Key | Wert (Typ) | Beschreibung |
---|---|---|
ssl.ClientCertificate | X509Certificate |
|
ssl.LoadClientCertAsync | Func<Task> |
|
server.RemoteIpAddress | String |
|
server.RemotePort | String |
|
server.LocalIpAddress | String |
|
server.LocalPort | String |
|
server.OnSendingHeaders | Action<Action<object>,object> |
SendFiles v0.3.0
Key | Wert (Typ) | Beschreibung |
---|---|---|
sendfile.SendAsync | Siehe Delegatsignatur | Pro Anforderung |
Opaque v0.3.0
Key | Wert (Typ) | Beschreibung |
---|---|---|
opaque.Version | String |
|
opaque.Upgrade | OpaqueUpgrade |
Siehe Delegatsignatur |
opaque.Stream | Stream |
|
opaque.CallCancelled | CancellationToken |
WebSocket v0.3.0
Key | Wert (Typ) | Beschreibung |
---|---|---|
websocket.Version | String |
|
websocket.Accept | WebSocketAccept |
Siehe Delegatsignatur |
websocket.AcceptAlt | n/v | |
websocket.SubProtocol | String |
Siehe RFC6455 Abschnitt 4.2.2, Schritt 5.5 |
websocket.SendAsync | WebSocketSendAsync |
Siehe Delegatsignatur |
websocket.ReceiveAsync | WebSocketReceiveAsync |
Siehe Delegatsignatur |
websocket.CloseAsync | WebSocketCloseAsync |
Siehe Delegatsignatur |
websocket.CallCancelled | CancellationToken |
|
websocket.ClientCloseStatus | int |
Optional |
websocket.ClientCloseDescription | String |
Optional |
Zusätzliche Ressourcen
- Informationen zu OWIN-Schlüsseln, die in der Übersetzungsebene unterstützt werden, finden Sie in der Quelle auf GitHub.
- Middleware
- Server