OWIN中间件可以使用http会话吗?

use*_*430 20 c# asp.net session httpsession owin

我有一些代码,我正在为ASP.NET和SignalR复制,我决定将其重写为OWIN中间件,以消除这种重复.

一旦我运行它,我注意到它HttpContext.Current.Session是null,我没有在IOwinContext我的中间件上看到任何会话对象.

是否可以从OWIN访问http会话?

Tra*_*her 29

是的,但这是一个非常黑客.它也不适用于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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用HttpContext.Current.Session或访问会话

HttpContextBase httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
Run Code Online (Sandbox Code Playgroud)

  • 我的会话仍为空.是什么导致的? (4认同)
  • @Rastko也许此会话黑客可以在IIS上与OWIN一起使用,但不能与自托管的OWIN一起使用。你在用哪个 (2认同)

Jer*_*oen 7

这个答案是初始答案的混音,所以它的要点应该归功于@Tratcher.虽然单独发布它而不是建议编辑,但它有足够的不同.


假设您想要为基本测试目的制作一个小型OWIN应用程序(例如,在进行集成测试时作为更大API的存根/伪造),包括使用会话状态的稍微有点hakish方式就可以正常工作.

首先,你需要这些:

using Microsoft.Owin;
using Microsoft.Owin.Extensions;
using Owin;
Run Code Online (Sandbox Code Playgroud)

有了这些,你可以创建一个帮助方法:

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);
}
Run Code Online (Sandbox Code Playgroud)

您也可以将其创建为原始答案所做的扩展方法.

请注意,如果您不使用,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);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

如果您使用这个小应用程序启动IIS Express,您将首先得到:

会话状态中没有数据.

如果你去,http://localhost:12345/write你会得到:

写到会话状态!

然后,如果您返回/转到该主机上的任何其他网址,您将获得:

11/4/2015 10:28:22 AM

或类似的东西.

  • 在***OnResponseSignIn***方法中,`System.Web.HttpContext.Current.Session`为null.代码:`Provider = new CookieAuthenticationProvider(){OnResponseSignIn = async context =>` (4认同)