18

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:

Community
  • 1
  • 1
Dan Solovay
  • 3,134
  • 3
  • 26
  • 55
  • 1
    I suspect it's because Sitecore inserts it's HttpModule ahead of the SessionState module, so you are running prior to session being created. – Derek Dysart Nov 13 '12 at 01:57

2 Answers2

23

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.

Community
  • 1
  • 1
Dan Solovay
  • 3,134
  • 3
  • 26
  • 55
7

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;
    }
}
Alex
  • 5,240
  • 1
  • 31
  • 38
  • Nice. Let me try it out, and then I will gladly give you my green check mark. :) Nice that you can do this inside Sitecore pipeline processors. – Dan Solovay Oct 31 '15 at 03:05
  • Sure let me know, actually you can either access your session by using HttpContext.current or args.context... – Rabehaja Harivola Loic Nov 01 '15 at 12:29
  • 1
    Confirmed. In my httpRequestProcessed pipeline processor, I was able to access args.HttpContext.Session and it wasn't null. – Aron Boyette Mar 20 '19 at 11:43
  • 1
    Worth noting this fires after renderings have processed, therefore they won't get the updated session information. – Jason Bert Dec 11 '20 at 14:08
  • @JasonBert Considering the fact that all pipelines within sitecore are being rendered within the same httprequest hence httpcontext, the session is pretty much available throughout that request. Furthermore, if you take a look at your pipelines' order you will see that httprequestprocess are rendered before the renderings are on the page. – Rabehaja Harivola Loic Oct 30 '21 at 21:47