Can OWIN middleware use the http session?

17,478

Solution 1

Yes, but it's quite a hack. It also won't work with SignalR because SignalR MUST run before session is acquired to prevent long session locks.

Do this to enable session for any request:

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

Then you can access the session with either HttpContext.Current.Session or

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

Solution 2

This answer is a remix from the initial answer, so the gist of it should be attributed to @Tratcher. It's different enough though to post it seperately instead of suggesting an edit.


Supposing you want to make a small OWIN app for basic testing purposes (e.g. as a stub/fake for a bigger API when doing integration tests), including a slightly hakish way of using session state would work just fine.

First up, you need these:

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

With those you can create a helper method:

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

You could also create that as an extension method as the original answer did.

Note that if you don't use the UseStageMarker you would encounter this error:

Server Error in '/' Application.
'HttpContext.SetSessionStateBehavior' can only be invoked before 'HttpApplication.AcquireRequestState' event is raised.

In any case, with the above you can now use HttpContext in your OWIN app like this:

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

If you fire up IIS Express with this little app you'll first get:

No data in session state yet.

Then if you go to http://localhost:12345/write you'll get:

Wrote to session state!

Then if you go back / go to any other url on that host you'll get:

11/4/2015 10:28:22 AM

Or something similar.

Share:
17,478

Related videos on Youtube

user2719430
Author by

user2719430

Updated on September 16, 2022

Comments

  • user2719430
    user2719430 over 1 year

    I had a little bit of code that I was duplicating for ASP.NET and SignalR and I decided to rewrite it as OWIN middleware to remove this duplication.

    Once I was running it I noticed that HttpContext.Current.Session was null, and I didn't see any session object on the IOwinContext that my middleware has.

    Is it possible to access the http session from OWIN?

  • Kiquenet
    Kiquenet almost 8 years
    System.Web.HttpContext.Current.Session is null in OnResponseSignIn method. Code: Provider = new CookieAuthenticationProvider() { OnResponseSignIn = async context =>
  • Rastko
    Rastko over 6 years
    My session is still null. What can cause that ?
  • Ananda G
    Ananda G about 6 years
    Same here, it's still null !!
  • BillVo
    BillVo almost 6 years
    @Rastko Perhaps this session hack works with OWIN on IIS but not self-hosted OWIN. Which were you using?
  • Tratcher
    Tratcher almost 6 years
    Correct, there is no session in selfhost.
  • Jeroen
    Jeroen over 3 years
    The session gets initialized in AcquireState stage. Any Owin middleware which runs before this stage e.g. through the use of app.UseStageMarker will encounter the session as null, regardless of this fix.