0

I have ApiControllers that access the session and by default has SessionState required. Therefore I am getting the requests serialized and would like to disable session state for specific requests.

In this post I have seen a solution for normal Controllers but I have no idea how to do it on ApiControllers.

This is my WebApiConfig

public static void Register(HttpConfiguration config)
    {
        RouteTable.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        ).RouteHandler = new SessionRouteHandler();

        config.Routes.MapHttpRoute(
            name: "Default2",
            routeTemplate: "api/{controller}"
        );
    }

And this is the SessionControllerHandler

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

public class SessionRouteHandler : IRouteHandler
{
    IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
    {
        return new SessionControllerHandler(requestContext.RouteData);
    }
}

Any help will be appreciated. Thank you

achecopar
  • 421
  • 1
  • 11
  • 20
  • I don't know anything about the specifics of how to enable session state in web API but from your code it seems that you do that when configuring the route. Then you should also be able to configure "normal" routes that doesn't enable session state. You even seem to have a `Default2` route for that but in your case the routing engine may always pick the `DefaultApi` route and thus enable session state. Actually, I'm a little confused by how `RouteTable` and `config` is used... – Martin Liversage Sep 16 '20 at 15:20
  • Please explain me how normal routes work for disabling the sesssion state in specific requests (actions) and not in the others within the same controller. I thought routes work only for the complete controller. I didn't touch the default code for RouteTable or RouteConfig, just registered the WebApiConfig. – achecopar Sep 16 '20 at 17:38
  • As I said, I don't know about the specifics of how to enable session state in Web API. However, by default I'm pretty sure that session state isn't enabled. This means that if you create a new Web API project you will have controllers and actions that doesn't use session state. You also seem to know how to create a controller that enables session state so to solve your problem you need two controllers: one with session state and another without. Place the actions on the respective controllers. The session state requirement should determine which controller an action is placed on. – Martin Liversage Sep 16 '20 at 18:40
  • I have a big project and it's already made with lots of controllers and actions, would rather disable for specific actions instead of making alot new controllers that dont have session state. That's why I asked how to do it for specific requests. I know it's possible for normal Controllers like in the post I mentioned, but ApiControllers dont use the SetControllerFactory mentioned there. There must be a way for ApiControllers too. – achecopar Sep 16 '20 at 19:46

1 Answers1

0

In order to not get the requests serialized, generate a new SessionControllerHandler for SessionState in ReadOnly mode

public class SessionControllerHandlerReadOnly : HttpControllerHandler, IReadOnlySessionState
{
    public SessionControllerHandlerReadOnly(RouteData routeData)
        : base(routeData)
    { }
}
public class SessionRouteHandlerReadOnly : IRouteHandler
{
    IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
    {
        return new SessionControllerHandlerReadOnly(requestContext.RouteData);
    }
} 

Then in the WebApiConfig add a new route that uses that handler

RouteTable.Routes.MapHttpRoute(
            name: "DefaultApiReadOnly",
            routeTemplate: "apireadonly/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        ).RouteHandler = new SessionRouteHandlerReadOnly();

Done, when you need a specific request going through that handler you specify it in the RouteUrl when making the request

@Url.RouteUrl("DefaultApiReadOnly", new { httproute = true, controller = "controller", action = "action" })
achecopar
  • 421
  • 1
  • 11
  • 20