Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing Session in HttpRequest Pipelines

Tags:

sitecore

I'm trying to access a query string parameter and save it to a Session variable. Since the solution I'm working on has several base layouts, the simplest approach would be to add this to a pipeline handler. However, my code is failing because args.Context.Session is null:

public class SaveQueryStringToSession : HttpRequestProcessor
{
    public override void Process(HttpRequestArgs args)
    {
        Assert.ArgumentNotNull((object)args, "args");
        string queryString = WebUtil.GetQueryString("parm1");
        if (queryString.Length <= 0)
            return;
        args.Context.Session["parm1"] = queryString;
    }
}

This occurs when this method is inserted into either the HttpRequestBegin or HttpRequestEnd pipeline. Curious to know why, and if there is a standard workaround or pattern to use here. (Yes, I will add a null check. No need to point that out.)

I'm running Sitecore Sitecore.NET 6.4.1 (rev. 110720) on IIS 7.5 (Integrated .Net 2.0)

Possibly relevant links:

  • What is the first global.asax event that Session is accessible assuming the context handler is IRequiresSessionState or IReadOnlySessionState?
  • http://intothecore.cassidy.dk/2009/02/session-state-and-integrated-pipeline.html
like image 348
Dan Solovay Avatar asked Nov 13 '12 01:11

Dan Solovay


2 Answers

The HttpRequestBegin pipeline is wired up to the HttpApplication.BeginRequest event, and this event is fired before the HttpSession object has been instantiated. Using the HttpRequestEnd pipeline does not work because the HttpSession object has already been disposed by the time the HttpApplication.EndRequest event is fired.

The session becomes available after the PostAcquireRequestState event is fired. To intercept this, create a class that implements IHttpModule, and add it to the <httpModules> element in Web.config. The HttpModule code will need to check if the request requires session state, as attempting to read the session for a static resource request will throw an exception.

Here is HttpModule code that accesses the Session and QueryString:

public class MyHttpModule :IHttpModule
{
   public void Init(HttpApplication context)
   {
       context.PostAcquireRequestState += RequestHandler;
   }

   public void Dispose()
   {
        //
   }

   public void RequestHandler(object sender, EventArgs e)
   {
       var app = (HttpApplication) sender;

       if (app.Context.Handler is IRequiresSessionState)
       {
           var session = app.Session;
           var queryString = app.Request.QueryString["test"];
           session["test"] = queryString;
       }
   }
}

It is worth noting that Sitecore's HttpRequestBegin and HttpRequestEnd pipelines are wired to ASP.NET via an HttpModule:

<add type="Sitecore.Nexus.Web.HttpModule,Sitecore.Nexus" 
name="SitecoreHttpModule" />

Thanks to @ddysart for pointing me in the right direction, and to this answer for the correct event to listen for.

like image 107
Dan Solovay Avatar answered Nov 13 '22 23:11

Dan Solovay


Actually instead of httpRequestBegin or HttpRequestEnd you can use httpRequestProcessed during which sitecore process the HttpRequest so you can access the Session.

You will be able to use the same code you have provided earlier.

public class SaveQueryStringToSession : HttpRequestProcessor
{
   public override void Process(HttpRequestArgs args)
   {
        Assert.ArgumentNotNull((object)args, "args");
        string queryString = WebUtil.GetQueryString("parm1");
        if (queryString.Length <= 0)
            return;
        args.Context.Session["parm1"] = queryString;
    }
}
like image 29
Rabehaja Harivola Loic Avatar answered Nov 13 '22 23:11

Rabehaja Harivola Loic