1

I have a request that is calling a third party service with multiple parameters. I would like to save one of the parameter value in the session for later use once the third party responds.

That third party service responds back to the call back service. In this callback service, I would like to use session variable that I created.

I tried creating a session variable using HttpContext.Current but the session is always null. I even tried inheriting my service stack class from IRequiresSessionState

public class CallThirdParty : IRequiresSessionState

public void Get(CallThirdParty request)
{
 HttpContext context = HttpContext.Current;
 var sessVariable = "test";
 context.Session["saveSession"] = sessVariable;
}

But the context.Session is always null? What is the best way to create a session variable in service stack or save the state for a single HttpRequest?

Learn AspNet
  • 1,192
  • 3
  • 34
  • 74

1 Answers1

2

ServiceStack's Sessions is a completely different implementation to ASP.NET Sessions which you're trying to use here.

For storing custom session info in unauthenticated requests you can use ServiceStack's SessionBag.

If you want to use ASP.NET Sessions in ServiceStack you can enable ASP.NET Sessions via a custom HttpHandlerFactory

namespace MyApp
{
    public class SessionHttpHandlerFactory : IHttpHandlerFactory
    {
        private static readonly HttpHandlerFactory Factory = new HttpHandlerFactory();

        public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string path)
        {
            var handler = Factory.GetHandler(context, requestType, url, path);
            return handler == null ? null : new SessionHandlerDecorator((IHttpAsyncHandler)handler);
        }

        public void ReleaseHandler(IHttpHandler handler) => Factory.ReleaseHandler(handler);
    }

    public class SessionHandlerDecorator : IHttpAsyncHandler, IRequiresSessionState
    {
        private IHttpAsyncHandler Handler { get; set; }

        internal SessionHandlerDecorator(IHttpAsyncHandler handler) => Handler = handler;

        public bool IsReusable => Handler.IsReusable;

        public void ProcessRequest(HttpContext context) => Handler.ProcessRequest(context);

        public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) => 
          Handler.BeginProcessRequest(context, cb, extraData);

        public void EndProcessRequest(IAsyncResult result) => Handler.EndProcessRequest(result);
    }
}

Then replace the existing ServiceStack.HttpHandlerFactory registration with your decorated implementation above, e.g:

<system.web>
  <httpHandlers>
    <add path="*" type="MyApp.SessionHttpHandlerFactory, MyApp" verb="*"/>
  </httpHandlers>
</system.web>

This is for recent ServiceStack v4.5+, for older versions you'll need to use a Sync Handler Factory.

mythz
  • 141,670
  • 29
  • 246
  • 390