web-dev-qa-db-ja.com

OWINミドルウェアはhttpセッションを使用できますか?

ASP.NETとSignalRのために複製していたコードが少しあったので、この重複を削除するためにOWINミドルウェアとして書き直すことにしました。

実行していたところ、HttpContext.Current.Sessionはnullで、ミドルウェアが持っているIOwinContextにセッションオブジェクトがありませんでした。

OWINからHTTPセッションにアクセスできますか?

21
user2719430

はい、しかしそれはかなりハックです。また、長いセッションロックを防ぐために、セッションを取得する前にSignalRを実行する必要があるため、SignalRとは連動しません。

これを実行して、すべての要求に対してセッションを有効にします。

public static class AspNetSessionExtensions
{
    public static IAppBuilder RequireAspNetSession(this IAppBuilder app)
    {
        app.Use((context, next) =>
        {
            // Depending on the handler the request gets mapped to, session might not be enabled. Force it on.
            HttpContextBase httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
            httpContext.SetSessionStateBehavior(SessionStateBehavior.Required);
            return next();
        });
        // SetSessionStateBehavior must be called before AcquireState
        app.UseStageMarker(PipelineStage.MapHandler);
        return app;
    }
}

次に、HttpContext.Current.Sessionまたは

HttpContextBase httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
29
Tratcher

この回答は 最初の回答 からのリミックスです。そのため、その要点は@Tratcherに帰属する必要があります。編集を提案するのではなく、個別に投稿するのとは異なります。


基本的なテストの目的で小さなOWINアプリを作成する場合(たとえば、統合テストを実行するときに、より大きなAPIのスタブ/フェイクとして)、セッション状態を使用する少し厄介な方法も問題なく機能するとします。

まず、次のものが必要です。

using Microsoft.Owin;
using Microsoft.Owin.Extensions;
using Owin;

これらを使用して、ヘルパーメソッドを作成できます。

public static void RequireAspNetSession(IAppBuilder app)
{
    app.Use((context, next) =>
    {
        var httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
        httpContext.SetSessionStateBehavior(SessionStateBehavior.Required);
        return next();
    });

    // To make sure the above `Use` is in the correct position:
    app.UseStageMarker(PipelineStage.MapHandler);
}

元の回答と同じように、それを拡張メソッドとして作成することもできます。

UseStageMarkerを使用しないと、次のエラーが発生することに注意してください。

「/」アプリケーションでのサーバーエラー
「HttpContext.SetSessionStateBehavior」は、「HttpApplication.AcquireRequestState」イベントが発生する前にのみ呼び出すことができます。

いずれにせよ、上記を使用すると、次のようにOWINアプリでHttpContextを使用できるようになります。

public void Configuration(IAppBuilder app)
{
    RequireAspNetSession(app);

    app.Run(async context =>
    {
        if (context.Request.Uri.AbsolutePath.EndsWith("write"))
        {
            HttpContext.Current.Session["data"] = DateTime.Now.ToString();
            await context.Response.WriteAsync("Wrote to session state!");
        }
        else
        {
            var data = (HttpContext.Current.Session["data"] ?? "No data in session state yet.").ToString();
            await context.Response.WriteAsync(data);
        }
    });
}

IISこの小さなアプリで表現すると、最初に次のようになります:

セッション状態のデータはまだありません。

次に、http://localhost:12345/write取得します:

セッション状態に書き込みました!

次に、戻った場合、またはそのホスト上の他のURLに移動した場合、次のようになります。

2015年11月4日10:28:22 AM

または似たようなもの。

9
Jeroen