Dowemo
0 0 0 0


Question:

I'm just getting started with ServiceStack and, as a test case, I am looking to rework an existing service which is built using standard ASP.Net handlers. I've managed to get it all working as I want it but have certain aspects which make use of the ASP.Net Session object.

I've tried adding IRequiresSessionState into the service interface:

public class SessionTestService : RestServiceBase<SessionTest>, IRequiresSessionState {
    public override object OnPost(SessionTest request) {
        // Here I want to use System.Web.HttpContext.Current.Session
    }
}

The trouble is I can't seem to get it to work as the Session object is always null.

I've done a lot of Googling and have puzzled over https://github.com/mythz/ServiceStack/blob/master/tests/ServiceStack.WebHost.IntegrationTests/Services/Secure.cs and similar but I can't find any example code which does this (which surprises me). Can anyone explain why the above doesn't work and advise what I need to do to get it working?

Note: Ultimately I'll probably look to replace this with Redis or will try to remove any serverside session requirement, but I figured that I'd use the ASP.Net implementation for the time being, to get things working and to avoid reworking it more than is necessary at this point.


Best Answer:


That's a great and comprehensive answer by @mythz. However, when trying to access the ASP.NET session by HttpContext.Current.Session within a ServiceStack web service, it always returns null for me. That's because none of the HttpHandlers within ServiceStack are adorned with the IRequiresSessionState interface, so the .NET Framework does not provide us with the session object.

To get around this, I've implemented two new classes, both of which use the decorator pattern to provide us with what we need.

Firstly, a new IHttpHandler which requires session state. It wraps the IHttpHandler provided by ServiceStack and passes calls through to it...

public class SessionHandlerDecorator : IHttpHandler, IRequiresSessionState {
    private IHttpHandler Handler { get; set; }
    internal SessionHandlerDecorator(IHttpHandler handler) {
        this.Handler = handler;
    }
    public bool IsReusable {
        get { return Handler.IsReusable; }
    }
    public void ProcessRequest(HttpContext context) {
        Handler.ProcessRequest(context);
    }
}

Next, a new IHttpHandlerFactory which delegates the responsibility for generating the IHttpHandler to ServiceStack, before wrapping the returned handler in our new SessionHandlerDecorator...

public class SessionHttpHandlerFactory : IHttpHandlerFactory {
    private readonly static ServiceStackHttpHandlerFactory factory = new ServiceStackHttpHandlerFactory();
    public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated) {
        var handler = factory.GetHandler(context, requestType, url, pathTranslated);
        return handler == null ? null : new SessionHandlerDecorator(handler);
    }
    public void ReleaseHandler(IHttpHandler handler) {
        factory.ReleaseHandler(handler);
    }
}

Then, it's just a matter of changing the type attributes in the handlers in Web.config to SessionHttpHandlerFactory instead of ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack, and your web services should now have the ASP.NET session avaialble to them.

Despite the above, I fully endorse the new ISession implementation provided by ServiceStack. However, in some cases, on a mature product, it just seems too big a job to replace all uses of the ASP.NET session with the new implementation, hence this workaround!




Copyright © 2011 Dowemo All rights reserved.    Creative Commons   AboutUs