Simon Miller Team : Web Development Tags : Web Development Tips & Tricks MVC

Enabling session state in Web API

Simon Miller Team : Web Development Tags : Web Development Tips & Tricks MVC

Some of you may look at this blog title and say “but you shouldn’t ever do that. Restful APIs are stateless, duh”. This is correct and is largely that way for philosophical reasons. But in practice, yes - you may need to access a user’s session from a web API.

By default this is not possible. Attempting to call HttpContext.Current.Session will always return null.

How do we get around this?

Registering a custom Web API route

There were a few answers available on the web but none of them worked correctly for me in MVC 5. The one that did was found in the book ASP.NET Web API 2 Recipes: A Problem-Solution Approach.

Create two classes; SessionControllerHandler and SessionHttpControllerRouteHandler. Implement as follows:

public class SessionControllerHandler : HttpControllerHandler, IRequiresSessionState
{
    public SessionControllerHandler(RouteData routeData)
        : base(routeData)
    { }
}

public class SessionHttpControllerRouteHandler : HttpControllerRouteHandler
{
    protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        return new SessionControllerHandler(requestContext.RouteData);
    }
}

In your WebApiConfig, add the following above your route declaration(s):

public static void Register(HttpConfiguration config)
{
    var httpControllerRouteHandler = typeof(HttpControllerRouteHandler).GetField("_instance", 
        System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);

    if (httpControllerRouteHandler != null)
    {
        httpControllerRouteHandler.SetValue(null,
            new Lazy<HttpControllerRouteHandler>(() => new SessionHttpControllerRouteHandler(), true));
    }

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{action}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
}

You will now find that any functions accessed through a Web API action will have access to read and write to session. Hooray!