--- title: Open Web Interface for .NET (OWIN) with ASP.NET Core 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. ms.author: riande ms.custom: H1Hack27Feb2017 ms.date: 2/8/2021 uid: fundamentals/owin --- # Open Web Interface for .NET (OWIN) with ASP.NET Core By [Steve Smith](https://ardalis.com/) and [Rick Anderson](https://twitter.com/RickAndMSFT) 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. 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: * ASP.NET Core to OWIN * OWIN to ASP.NET Core 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. [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)) ## Running OWIN middleware in the ASP.NET Core pipeline 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. OWIN middleware conforms to the [OWIN specification](https://owin.org/spec/spec/owin-1.0.0.html), which requires a `Func, Task>` interface, and specific keys be set (such as `owin.ResponseBody`). The following simple OWIN middleware displays "Hello World": ```csharp public Task OwinHello(IDictionary 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)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); } ``` The sample signature returns a `Task` and accepts an `IDictionary` 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. ```csharp public void Configure(IApplicationBuilder app) { app.UseOwin(pipeline => { pipeline(next => OwinHello); }); } ``` 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. ```csharp app.UseOwin(pipeline => { pipeline(next => { return async environment => { // Do something before. await next(environment); // Do something after. }; }); }); ``` ## OWIN environment You can construct an OWIN environment using the `HttpContext`. ```csharp var environment = new OwinEnvironment(HttpContext); var features = new OwinFeatureCollection(environment); ``` ## OWIN keys OWIN depends on an `IDictionary` 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). ### Request data (OWIN v1.0.0) | 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` | | | owin.RequestBody | `Stream` | | ### Request data (OWIN v1.1.0) | Key | Value (type) | Description | | ----------------- | ------------ | ----------- | | owin.RequestId | `String` | Optional | ### Response data (OWIN v1.0.0) | Key | Value (type) | Description | | ----------------- | ------------ | ----------- | | owin.ResponseStatusCode | `int` | Optional | | owin.ResponseReasonPhrase | `String` | Optional | | owin.ResponseHeaders | `IDictionary` | | | owin.ResponseBody | `Stream` | | ### Other data (OWIN v1.0.0) | Key | Value (type) | Description | | ----------------- | ------------ | ----------- | | owin.CallCancelled | `CancellationToken` | | | owin.Version | `String` | | ### Common keys | Key | Value (type) | Description | | ----------------- | ------------ | ----------- | | ssl.ClientCertificate | `X509Certificate` | | | ssl.LoadClientCertAsync | `Func` | | | server.RemoteIpAddress | `String` | | | server.RemotePort | `String` | | | server.LocalIpAddress | `String` | | | server.LocalPort | `String` | | | server.OnSendingHeaders | `Action,object>` | | ### SendFiles v0.3.0 | Key | Value (type) | Description | | ----------------- | ------------ | ----------- | | sendfile.SendAsync | See [delegate signature](https://owin.org/spec/extensions/owin-SendFile-Extension-v0.3.0.htm) | Per Request | ### Opaque v0.3.0 | Key | Value (type) | Description | | ----------------- | ------------ | ----------- | | opaque.Version | `String` | | | opaque.Upgrade | `OpaqueUpgrade` | See [delegate signature](https://owin.org/spec/extensions/owin-SendFile-Extension-v0.3.0.htm) | | opaque.Stream | `Stream` | | | opaque.CallCancelled | `CancellationToken` | | ### WebSocket v0.3.0 | Key | Value (type) | Description | | ----------------- | ------------ | ----------- | | websocket.Version | `String` | | | websocket.Accept | `WebSocketAccept` | See [delegate signature](https://owin.org/spec/extensions/owin-SendFile-Extension-v0.3.0.htm) | | 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 | | 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) | | websocket.CallCancelled | `CancellationToken` | | | websocket.ClientCloseStatus | `int` | Optional | | websocket.ClientCloseDescription | `String` | Optional | ## Additional resources * 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)