具有 ASP.NET Core 的 Open Web Interface for .NET (OWIN)Open Web Interface for .NET (OWIN) with ASP.NET Core

作者:Steve SmithRick AndersonBy Steve Smith and Rick Anderson

ASP.NET Core:ASP.NET Core:

  • 支援 Open Web Interface for .NET (OWIN) 。Supports the Open Web Interface for .NET (OWIN).
  • 針對 Microsoft.Owin.* (Katana) 程式庫具有 .net Core 相容的取代。Has .NET Core compatible replacements for the Microsoft.Owin.* (Katana) libraries.

OWIN 可讓 Web 應用程式獨立於網頁伺服器。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 應用程式和中介軟體可以與以 OWIN 為基礎的應用程式、伺服器及中介軟體進行交互操作。ASP.NET Core applications and middleware can interoperate with OWIN-based applications, servers, and middleware.

OWIN 提供分離層,可讓兩個利用不同物件模型的架構一起使用。OWIN provides a decoupling layer that allows two frameworks with disparate object models to be used together. Microsoft.AspNetCore.Owin 套件提供兩個配接器實作:The Microsoft.AspNetCore.Owin package provides two adapter implementations:

  • ASP.NET Core 至 OWINASP.NET Core to OWIN
  • OWIN 至 ASP.NET CoreOWIN to ASP.NET Core

這可讓 ASP.NET Core 裝載在 OWIN 相容的伺服器/主機之上,或讓其他 OWIN 相容的元件在 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.

注意

使用這些配接器將伴隨效能成本增加。Using these adapters comes with a performance cost. 僅使用 ASP.NET Core 元件的應用程式不應使用 Microsoft.AspNetCore.Owin 套件或配接器。Apps using only ASP.NET Core components shouldn't use the Microsoft.AspNetCore.Owin package or adapters.

查看或下載範例程式碼 (如何下載) View or download sample code (how to download)

在 ASP.NET Core 管線中執行 OWIN 中介軟體Running OWIN middleware in the ASP.NET Core pipeline

ASP.NET Core 的 OWIN 支援部署為 Microsoft.AspNetCore.Owin 套件的一部分。ASP.NET Core's OWIN support is deployed as part of the Microsoft.AspNetCore.Owin package. 您可以藉由安裝此套件,將 OWIN 支援匯入您的專案中。You can import OWIN support into your project by installing this package.

OWIN 中介軟體符合 OWIN 規格,它需要設定 Func<IDictionary<string, object>, Task> 介面和特定的索引鍵 (例如 owin.ResponseBody)。OWIN middleware conforms to the OWIN specification, which requires a Func<IDictionary<string, object>, Task> interface, and specific keys be set (such as owin.ResponseBody). 下列簡單的 OWIN 中介軟體會顯示 "Hello World":The following simple OWIN middleware displays "Hello World":

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

範例簽章會傳回 Task,並依照 OWIN 的要求接受 IDictionary<string, object>The sample signature returns a Task and accepts an IDictionary<string, object> as required by OWIN.

下列程式碼示範如何使用 UseOwin 擴充方法,將 OwinHello 中介軟體 (如上所示) 新增至 ASP.NET Core 管線。The following code shows how to add the OwinHello middleware (shown above) to the ASP.NET Core pipeline with the UseOwin extension method.

public void Configure(IApplicationBuilder app)
{
    app.UseOwin(pipeline =>
    {
        pipeline(next => OwinHello);
    });
}

您可以設定在 OWIN 管線內進行其他動作。You can configure other actions to take place within the OWIN pipeline.

注意

只能在第一次寫入回應資料流之前修改回應標頭。Response headers should only be modified prior to the first write to the response stream.

注意

基於效能考量,建議您不要多次呼叫 UseOwinMultiple calls to UseOwin is discouraged for performance reasons. OWIN 元件如果群組在一起,其運作效能最佳。OWIN components will operate best if grouped together.

app.UseOwin(pipeline =>
{
    pipeline(next =>
    {
        return async environment =>
        {
            // Do something before.
            await next(environment);
            // Do something after.
        };
    });
});

在以 OWIN 為基礎的伺服器上執行 ASP.NET Core 並使用其 WebSocket 支援Run ASP.NET Core on an OWIN-based server and use its WebSockets support

ASP.NET Core 如何利用以 OWIN 為基礎之伺服器功能的另一個範例是存取 WebSocket 等功能。Another example of how OWIN-based servers' features can be leveraged by ASP.NET Core is access to features like WebSockets. 在上述範例中使用的 .NET OWIN 網頁伺服器支援內建的 Web 通訊端,供 ASP.NET Core 應用程式加以利用。The .NET OWIN web server used in the previous example has support for Web Sockets built in, which can be leveraged by an ASP.NET Core application. 下列範例顯示的簡單 Web 應用程式支援 Web 通訊端,並透過 Websocket 回應傳送至伺服器的所有項目。The example below shows a simple web app that supports Web Sockets and echoes back everything sent to the server through WebSockets.

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 環境OWIN environment

您可以使用 HttpContext 建構 OWIN 環境。You can construct an OWIN environment using the HttpContext.


   var environment = new OwinEnvironment(HttpContext);
   var features = new OwinFeatureCollection(environment);

OWIN 索引鍵OWIN keys

OWIN 仰賴 IDictionary<string,object> 物件在 HTTP 要求/回應交換中傳遞資訊。OWIN depends on an IDictionary<string,object> object to communicate information throughout an HTTP Request/Response exchange. ASP.NET Core 會實作下面所列的索引鍵。ASP.NET Core implements the keys listed below. 請參閱主要規格、模組延伸OWIN Key Guidelines and Common Keys (OWIN 索引鍵指導方針和共用索引鍵)。See the primary specification, extensions, and OWIN Key Guidelines and Common Keys.

要求資料 (OWIN 1.0.0 版)Request data (OWIN v1.0.0)

答案Key 值 (類型)Value (type) DescriptionDescription
owin.RequestSchemeowin.RequestScheme String
owin.RequestMethodowin.RequestMethod String
owin.RequestPathBaseowin.RequestPathBase String
owin.RequestPathowin.RequestPath String
owin.RequestQueryStringowin.RequestQueryString String
owin.RequestProtocolowin.RequestProtocol String
owin.RequestHeadersowin.RequestHeaders IDictionary<string,string[]>
owin.RequestBodyowin.RequestBody Stream

要求資料 (OWIN 1.1.0 版)Request data (OWIN v1.1.0)

答案Key 值 (類型)Value (type) DescriptionDescription
owin.RequestIdowin.RequestId String 選擇性Optional

回應資料 (OWIN 1.0.0 版)Response data (OWIN v1.0.0)

答案Key 值 (類型)Value (type) DescriptionDescription
owin.ResponseStatusCodeowin.ResponseStatusCode int 選擇性Optional
owin.ResponseReasonPhraseowin.ResponseReasonPhrase String 選擇性Optional
owin.ResponseHeadersowin.ResponseHeaders IDictionary<string,string[]>
owin.ResponseBodyowin.ResponseBody Stream

其他資料 (OWIN 1.0.0 版)Other data (OWIN v1.0.0)

答案Key 值 (類型)Value (type) DescriptionDescription
owin.CallCancelledowin.CallCancelled CancellationToken
owin.Versionowin.Version String

共同索引鍵Common keys

答案Key 值 (類型)Value (type) DescriptionDescription
ssl.ClientCertificatessl.ClientCertificate X509Certificate
ssl.LoadClientCertAsyncssl.LoadClientCertAsync Func<Task>
server.RemoteIpAddressserver.RemoteIpAddress String
server.RemotePortserver.RemotePort String
server.LocalIpAddressserver.LocalIpAddress String
server.LocalPortserver.LocalPort String
server.IsLocalserver.IsLocal bool
server.OnSendingHeadersserver.OnSendingHeaders Action<Action<object>,object>

SendFiles 0.3.0 版SendFiles v0.3.0

答案Key 值 (類型)Value (type) DescriptionDescription
sendfile.SendAsyncsendfile.SendAsync 請參閱委派簽章See delegate signature 每個要求Per Request

Opaque 0.3.0 版Opaque v0.3.0

答案Key 值 (類型)Value (type) DescriptionDescription
opaque.Versionopaque.Version String
opaque.Upgradeopaque.Upgrade OpaqueUpgrade 請參閱委派簽章See delegate signature
opaque.Streamopaque.Stream Stream
opaque.CallCancelledopaque.CallCancelled CancellationToken

WebSocket 0.3.0 版WebSocket v0.3.0

答案Key 值 (類型)Value (type) DescriptionDescription
websocket.Versionwebsocket.Version String
websocket.Acceptwebsocket.Accept WebSocketAccept 請參閱委派簽章See delegate signature
websocket.AcceptAltwebsocket.AcceptAlt 非規格Non-spec
websocket.SubProtocolwebsocket.SubProtocol String 請參閱 RFC6455 4.2.2 節的步驟 5.5See RFC6455 Section 4.2.2 Step 5.5
websocket.SendAsyncwebsocket.SendAsync WebSocketSendAsync 請參閱委派簽章See delegate signature
websocket.ReceiveAsyncwebsocket.ReceiveAsync WebSocketReceiveAsync 請參閱委派簽章See delegate signature
websocket.CloseAsyncwebsocket.CloseAsync WebSocketCloseAsync 請參閱委派簽章See delegate signature
websocket.CallCancelledwebsocket.CallCancelled CancellationToken
websocket.ClientCloseStatuswebsocket.ClientCloseStatus int 選擇性Optional
websocket.ClientCloseDescriptionwebsocket.ClientCloseDescription String 選擇性Optional

其他資源Additional resources