Open Web Interface for .NET (OWIN) と ASP.NET CoreOpen Web Interface for .NET (OWIN) with ASP.NET Core

作成者: Steve SmithRick AndersonBy Steve Smith and Rick Anderson

ASP.NET Core は、Open Web Interface for .NET (OWIN) をサポートします。ASP.NET Core supports the Open Web Interface for .NET (OWIN). OWIN により、Web アプリを 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 には、さまざまなオブジェクト モデルを使用する 2 つのフレームワークを併用できる分離レイヤーがあります。OWIN provides a decoupling layer that allows two frameworks with disparate object models to be used together. Microsoft.AspNetCore.Owin パッケージには 2 つのアダプター実装が用意されています。The Microsoft.AspNetCore.Owin package provides two adapter implementations:

  • ASP.NET Core から OWIN へASP.NET Core to OWIN
  • OWIN から ASP.NET Core へOWIN 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 ミドルウェアは、Func<IDictionary<string, object>, Task> インターフェイスと特定のキー (owin.ResponseBody など) の設定を必須とする OWIN 仕様に準拠しています。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 拡張メソッドを使用して ASP.NET Core パイプラインに OwinHello ミドルウェア (上の図) を追加する方法を示しています。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.

注意

パフォーマンス上の理由から、UseOwin を複数回、呼び出すことは避けてください。Multiple 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 ホスティングを使用するUsing ASP.NET Core Hosting on an OWIN-based server

OWIN ベースのサーバーは、ASP.NET Core アプリをホストできます。OWIN-based servers can host ASP.NET Core apps. たとえば、.NET OWIN Web サーバーである Nowin です。One such server is Nowin, a .NET OWIN web server. この記事のサンプルには ​​Nowin を参照するプロジェクトを含めました。また、それを使用して ASP.NET Core を自己ホスティングできる IServer を作成しています。In the sample for this article, I've included a project that references Nowin and uses it to create an IServer capable of self-hosting ASP.NET Core.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;

namespace NowinSample
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
                .UseNowin()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseIISIntegration()
                .UseStartup<Startup>()
                .Build();

            host.Run();
        }
    }
}

IServer は、Features プロパティと Start メソッドを必要とするインターフェイスです。IServer is an interface that requires a Features property and a Start method.

Start はサーバーの構成と起動を担当します。この例では、IServerAddressesFeature から解析されたアドレスを設定する一連の fluent API 呼び出しによって行われます。Start is responsible for configuring and starting the server, which in this case is done through a series of fluent API calls that set addresses parsed from the IServerAddressesFeature. _builder 変数の fluent 構成によって、メソッドの前半で定義された appFunc が要求を処理するように指定されている点に注意してください。Note that the fluent configuration of the _builder variable specifies that requests will be handled by the appFunc defined earlier in the method. この Func は、受信要求を処理するたびに呼び出されます。This Func is called on each request to process incoming requests.

また、Nowin サーバーの追加と構成を簡単に行うための IWebHostBuilder 拡張機能も追加します。We'll also add an IWebHostBuilder extension to make it easy to add and configure the Nowin server.

using System;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.Extensions.DependencyInjection;
using Nowin;
using NowinSample;

namespace Microsoft.AspNetCore.Hosting
{
    public static class NowinWebHostBuilderExtensions
    {
        public static IWebHostBuilder UseNowin(this IWebHostBuilder builder)
        {
            return builder.ConfigureServices(services =>
            {
                services.AddSingleton<IServer, NowinServer>();
            });
        }

        public static IWebHostBuilder UseNowin(this IWebHostBuilder builder, Action<ServerBuilder> configure)
        {
            builder.ConfigureServices(services =>
            {
                services.Configure(configure);
            });
            return builder.UseNowin();
        }
    }
}

これが配置された状態で、Program.cs で拡張機能を呼び出し、このカスタム サーバーを利用して ASP.NET Core アプリを実行します。With this in place, invoke the extension in Program.cs to run an ASP.NET Core app using this custom server:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;

namespace NowinSample
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
                .UseNowin()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseIISIntegration()
                .UseStartup<Startup>()
                .Build();

            host.Run();
        }
    }
}

ASP.NET Core サーバーの詳細については、こちらを参照してください。Learn more about ASP.NET Core Servers.

OWIN ベースのサーバー上で ASP.NET Core を実行し、その WebSockets のサポートを利用するRun ASP.NET Core on an OWIN-based server and use its WebSockets support

OWIN ベースのサーバーの機能を ASP.NET Core で利用する方法のもう 1 つの例として、WebSockets などの機能へのアクセスが挙げられます。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 アプリケーションから利用できる組み込みの Web Sockets をサポートしています。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 Sockets をサポートし、WebSockets を介してサーバーに送信されたすべてをエコー バックする単純な Web アプリケーションの例を次に示します。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);
    }
}

このサンプルは、前のサンプルと同じ NowinServer を使用して構成されています。唯一の違いは、アプリケーションがその Configure メソッドでどのように構成されているかです。This sample is configured using the same NowinServer as the previous one - the only difference is in how the application is configured in its Configure method. 単純な websocket クライアントを使用したテストで、アプリケーションについて説明します。A test using a simple websocket client demonstrates the application:

Web ソケットのテスト クライアント

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 は、HTTP 要求/応答の交換を通じて情報を伝達するために IDictionary<string,object> オブジェクトに依存しています。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 v1.0.0)Request data (OWIN v1.0.0)

KeyKey 値 (型)Value (type) 説明Description
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 v1.1.0)Request data (OWIN v1.1.0)

KeyKey 値 (型)Value (type) 説明Description
owin.RequestIdowin.RequestId String OptionalOptional

応答データ (OWIN v1.0.0)Response data (OWIN v1.0.0)

KeyKey 値 (型)Value (type) 説明Description
owin.ResponseStatusCodeowin.ResponseStatusCode int OptionalOptional
owin.ResponseReasonPhraseowin.ResponseReasonPhrase String OptionalOptional
owin.ResponseHeadersowin.ResponseHeaders IDictionary<string,string[]>
owin.ResponseBodyowin.ResponseBody Stream

その他のデータ (OWIN v1.0.0)Other data (OWIN v1.0.0)

KeyKey 値 (型)Value (type) 説明Description
owin.CallCancelledowin.CallCancelled CancellationToken
owin.Versionowin.Version String

共通キーCommon keys

KeyKey 値 (型)Value (type) 説明Description
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 v0.3.0SendFiles v0.3.0

KeyKey 値 (型)Value (type) 説明Description
sendfile.SendAsyncsendfile.SendAsync Delegate Signature」(デリゲート シグネチャ) を参照してください。See delegate signature 要求ごとPer Request

Opaque v0.3.0Opaque v0.3.0

KeyKey 値 (型)Value (type) 説明Description
opaque.Versionopaque.Version String
opaque.Upgradeopaque.Upgrade OpaqueUpgrade Delegate Signature」(デリゲート シグネチャ) を参照してください。See delegate signature
opaque.Streamopaque.Stream Stream
opaque.CallCancelledopaque.CallCancelled CancellationToken

WebSocket v0.3.0WebSocket v0.3.0

KeyKey 値 (型)Value (type) 説明Description
websocket.Versionwebsocket.Version String
websocket.Acceptwebsocket.Accept WebSocketAccept Delegate Signature」(デリゲート シグネチャ) を参照してください。See delegate signature
websocket.AcceptAltwebsocket.AcceptAlt 記述なしNon-spec
websocket.SubProtocolwebsocket.SubProtocol String RFC6455 のセクション 4.2.2 の手順 5.5 を参照してください。See RFC6455 Section 4.2.2 Step 5.5
websocket.SendAsyncwebsocket.SendAsync WebSocketSendAsync Delegate Signature」(デリゲート シグネチャ) を参照してください。See delegate signature
websocket.ReceiveAsyncwebsocket.ReceiveAsync WebSocketReceiveAsync Delegate Signature」(デリゲート シグネチャ) を参照してください。See delegate signature
websocket.CloseAsyncwebsocket.CloseAsync WebSocketCloseAsync Delegate Signature」(デリゲート シグネチャ) を参照してください。See delegate signature
websocket.CallCancelledwebsocket.CallCancelled CancellationToken
websocket.ClientCloseStatuswebsocket.ClientCloseStatus int OptionalOptional
websocket.ClientCloseDescriptionwebsocket.ClientCloseDescription String OptionalOptional

その他の技術情報Additional resources