AspNetCore.Docs/aspnetcore/fundamentals/owin.md

189 lines
7.9 KiB
Markdown
Raw Normal View History

2016-10-29 01:35:15 +08:00
---
title: Open Web Interface for .NET (OWIN) with ASP.NET Core
2016-11-12 00:28:14 +08:00
author: ardalis
description: Discover how ASP.NET Core supports the Open Web Interface for .NET (OWIN), which allows web apps to be decoupled from web servers.
2018-01-29 23:21:31 +08:00
ms.author: riande
ms.custom: H1Hack27Feb2017
ms.date: 2/8/2021
2016-10-29 01:35:15 +08:00
uid: fundamentals/owin
---
# Open Web Interface for .NET (OWIN) with ASP.NET Core
2016-10-29 01:35:15 +08:00
2018-06-30 23:38:29 +08:00
By [Steve Smith](https://ardalis.com/) and [Rick Anderson](https://twitter.com/RickAndMSFT)
2016-10-29 01:35:15 +08:00
ASP.NET Core:
* Supports the Open Web Interface for .NET (OWIN).
* Has .NET Core compatible replacements for the `Microsoft.Owin.*` ([Katana](/aspnet/aspnet/overview/owin-and-katana/)) libraries.
OWIN allows web apps to be decoupled from web servers. It defines a standard way for middleware to be used in a pipeline to handle requests and associated responses. ASP.NET Core applications and middleware can interoperate with OWIN-based applications, servers, and middleware.
2016-10-29 01:35:15 +08:00
2017-04-25 09:55:55 +08:00
OWIN provides a decoupling layer that allows two frameworks with disparate object models to be used together. The `Microsoft.AspNetCore.Owin` package provides two adapter implementations:
2018-06-30 23:38:29 +08:00
* ASP.NET Core to OWIN
* OWIN to ASP.NET Core
2017-04-25 09:55:55 +08:00
2018-06-30 23:38:29 +08:00
This allows ASP.NET Core to be hosted on top of an OWIN compatible server/host or for other OWIN compatible components to be run on top of ASP.NET Core.
> [!NOTE]
> Using these adapters comes with a performance cost. Apps using only ASP.NET Core components shouldn't use the `Microsoft.AspNetCore.Owin` package or adapters.
2017-04-25 09:55:55 +08:00
2021-03-10 12:40:27 +08:00
[View or download sample code](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/owin/sample) ([how to download](xref:index#how-to-download-a-sample))
2016-10-29 01:35:15 +08:00
## Running OWIN middleware in the ASP.NET Core pipeline
2016-10-29 01:35:15 +08:00
ASP.NET Core's OWIN support is deployed as part of the `Microsoft.AspNetCore.Owin` package. You can import OWIN support into your project by installing this package.
2016-10-29 01:35:15 +08:00
2019-07-11 10:36:05 +08:00
OWIN middleware conforms to the [OWIN specification](https://owin.org/spec/spec/owin-1.0.0.html), which requires a `Func<IDictionary<string, object>, Task>` interface, and specific keys be set (such as `owin.ResponseBody`). The following simple OWIN middleware displays "Hello World":
2016-10-29 01:35:15 +08:00
2016-11-18 13:03:07 +08:00
```csharp
2016-10-29 01:35:15 +08:00
public Task OwinHello(IDictionary<string, object> environment)
{
string responseText = "Hello World via OWIN";
byte[] responseBytes = Encoding.UTF8.GetBytes(responseText);
2019-07-11 10:36:05 +08:00
// OWIN Environment Keys: https://owin.org/spec/spec/owin-1.0.0.html
2016-10-29 01:35:15 +08:00
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);
}
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
The sample signature returns a `Task` and accepts an `IDictionary<string, object>` as required by OWIN.
The following code shows how to add the `OwinHello` middleware (shown above) to the ASP.NET Core pipeline with the `UseOwin` extension method.
2016-10-29 01:35:15 +08:00
2016-11-18 13:03:07 +08:00
```csharp
2016-10-29 01:35:15 +08:00
public void Configure(IApplicationBuilder app)
{
app.UseOwin(pipeline =>
{
pipeline(next => OwinHello);
});
}
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
You can configure other actions to take place within the OWIN pipeline.
> [!NOTE]
> Response headers should only be modified prior to the first write to the response stream.
> [!NOTE]
> Multiple calls to `UseOwin` is discouraged for performance reasons. OWIN components will operate best if grouped together.
2016-11-18 13:03:07 +08:00
```csharp
2016-10-29 01:35:15 +08:00
app.UseOwin(pipeline =>
{
pipeline(next =>
2016-10-29 01:35:15 +08:00
{
return async environment =>
{
// Do something before.
await next(environment);
// Do something after.
};
2016-10-29 01:35:15 +08:00
});
});
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
## OWIN environment
You can construct an OWIN environment using the `HttpContext`.
2016-10-29 01:35:15 +08:00
2016-11-18 13:03:07 +08:00
```csharp
2016-10-29 01:35:15 +08:00
var environment = new OwinEnvironment(HttpContext);
var features = new OwinFeatureCollection(environment);
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
## OWIN keys
2019-07-11 10:36:05 +08:00
OWIN depends on an `IDictionary<string,object>` object to communicate information throughout an HTTP Request/Response exchange. ASP.NET Core implements the keys listed below. See the [primary specification, extensions](https://owin.org/#spec), and [OWIN Key Guidelines and Common Keys](https://owin.org/spec/spec/CommonKeys.html).
2016-10-29 01:35:15 +08:00
### Request data (OWIN v1.0.0)
2016-10-29 01:35:15 +08:00
| Key | Value (type) | Description |
| ----------------- | ------------ | ----------- |
| 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` | |
### Request data (OWIN v1.1.0)
2016-10-29 01:35:15 +08:00
| Key | Value (type) | Description |
| ----------------- | ------------ | ----------- |
| owin.RequestId | `String` | Optional |
### Response data (OWIN v1.0.0)
2016-10-29 01:35:15 +08:00
| Key | Value (type) | Description |
| ----------------- | ------------ | ----------- |
| owin.ResponseStatusCode | `int` | Optional |
| owin.ResponseReasonPhrase | `String` | Optional |
| owin.ResponseHeaders | `IDictionary<string,string[]>` | |
| owin.ResponseBody | `Stream` | |
### Other data (OWIN v1.0.0)
2016-10-29 01:35:15 +08:00
| Key | Value (type) | Description |
| ----------------- | ------------ | ----------- |
| owin.CallCancelled | `CancellationToken` | |
| owin.Version | `String` | |
### Common keys
2016-10-29 01:35:15 +08:00
| Key | Value (type) | Description |
| ----------------- | ------------ | ----------- |
| 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 | Value (type) | Description |
| ----------------- | ------------ | ----------- |
2019-07-11 10:36:05 +08:00
| sendfile.SendAsync | See [delegate signature](https://owin.org/spec/extensions/owin-SendFile-Extension-v0.3.0.htm) | Per Request |
2016-10-29 01:35:15 +08:00
### Opaque v0.3.0
| Key | Value (type) | Description |
| ----------------- | ------------ | ----------- |
| opaque.Version | `String` | |
2019-07-11 10:36:05 +08:00
| opaque.Upgrade | `OpaqueUpgrade` | See [delegate signature](https://owin.org/spec/extensions/owin-SendFile-Extension-v0.3.0.htm) |
2016-10-29 01:35:15 +08:00
| opaque.Stream | `Stream` | |
| opaque.CallCancelled | `CancellationToken` | |
### WebSocket v0.3.0
| Key | Value (type) | Description |
| ----------------- | ------------ | ----------- |
| websocket.Version | `String` | |
2019-07-11 10:36:05 +08:00
| websocket.Accept | `WebSocketAccept` | See [delegate signature](https://owin.org/spec/extensions/owin-SendFile-Extension-v0.3.0.htm) |
2016-10-29 01:35:15 +08:00
| websocket.AcceptAlt | | Non-spec |
| websocket.SubProtocol | `String` | See [RFC6455 Section 4.2.2](https://tools.ietf.org/html/rfc6455#section-4.2.2) Step 5.5 |
2019-07-11 10:36:05 +08:00
| websocket.SendAsync | `WebSocketSendAsync` | See [delegate signature](https://owin.org/spec/extensions/owin-SendFile-Extension-v0.3.0.htm) |
| websocket.ReceiveAsync | `WebSocketReceiveAsync` | See [delegate signature](https://owin.org/spec/extensions/owin-SendFile-Extension-v0.3.0.htm) |
| websocket.CloseAsync | `WebSocketCloseAsync` | See [delegate signature](https://owin.org/spec/extensions/owin-SendFile-Extension-v0.3.0.htm) |
2016-10-29 01:35:15 +08:00
| websocket.CallCancelled | `CancellationToken` | |
| websocket.ClientCloseStatus | `int` | Optional |
| websocket.ClientCloseDescription | `String` | Optional |
## Additional resources
2016-10-29 01:35:15 +08:00
2023-02-10 09:42:44 +08:00
* See the [source on GitHub](https://github.com/aspnet/HttpAbstractions/blob/524a0227e5b7945b9520855d37881dabf7e5da32/src/Microsoft.AspNetCore.Owin/OwinFeatureCollection.cs) for OWIN keys supported in the translation layer.
* [Middleware](xref:fundamentals/middleware/index)
* [Servers](xref:fundamentals/servers/index)