4

In my program I'm trying to use session variable in IHttpModule. Here is my code. This is working fine in VS 2010 development server. But when I try to debug in IIS7 it shows exception System.Web.HttpException: Session state is not available in this context So why session not available in IIS 7 but in development server.

using System;
using System.Web;

public class Globalizer : IHttpModule
{    
  public void Init(HttpApplication context)
  {
    context.AcquireRequestState += new EventHandler(setLanguage);
  }

  public void Dispose(){}

  public void setLanguage(Object sender, EventArgs i_eventArgs)
  {
    HttpApplication http_application = sender as HttpApplication;     
    http_application.Session["language"] = "test";

  }
}
Nayana Adassuriya
  • 23,596
  • 30
  • 104
  • 147

4 Answers4

1

All you need is to implement IRequiresSessionState.

So your code should look like:

public class Globalizer : IHttpModule, IRequiresSessionState

if all you use is reading Sessions (and never update them) then you should use IReadOnlySessionState as this last do not lock the session state, and therefor, you will not have concurrent requests).

balexandre
  • 73,608
  • 45
  • 233
  • 342
0

If possible, move your handler to a PostAcquireRequestState handler:

Occurs when the request state (for example, session state) that is associated with the current request has been obtained.

(Or an even later event)

The SessionStateModule itself loads session state in response to the AcquireRequestState event - So at the moment, you're depending on whether your module or the session state module's handlers fire first.

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
  • Damien_The_Unbeliever- thank you for the idea. But it doesn't work. same exception. I'm wondering how my program works in development server? – Nayana Adassuriya Jan 16 '14 at 07:47
0

Found this over on the ASP.NET forums:

using System;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using System.Diagnostics;

// This code demonstrates how to make session state available in HttpModule,
// regradless of requested resource.
// author: Tomasz Jastrzebski

public class MyHttpModule : IHttpModule
{
   public void Init(HttpApplication application)
   {
      application.PostAcquireRequestState += new EventHandler(Application_PostAcquireRequestState);
      application.PostMapRequestHandler += new EventHandler(Application_PostMapRequestHandler);
   }

   void Application_PostMapRequestHandler(object source, EventArgs e)
   {
      HttpApplication app = (HttpApplication)source;

      if (app.Context.Handler is IReadOnlySessionState || app.Context.Handler is IRequiresSessionState) {
         // no need to replace the current handler
         return;
      }

      // swap the current handler
      app.Context.Handler = new MyHttpHandler(app.Context.Handler);
   }

   void Application_PostAcquireRequestState(object source, EventArgs e)
   {
      HttpApplication app = (HttpApplication)source;

      MyHttpHandler resourceHttpHandler = HttpContext.Current.Handler as MyHttpHandler;

      if (resourceHttpHandler != null) {
         // set the original handler back
         HttpContext.Current.Handler = resourceHttpHandler.OriginalHandler;
      }

      // -> at this point session state should be available

      Debug.Assert(app.Session != null, "it did not work :(");
   }

   public void Dispose()
   {

   }

   // a temp handler used to force the SessionStateModule to load session state
   public class MyHttpHandler : IHttpHandler, IRequiresSessionState
   {
      internal readonly IHttpHandler OriginalHandler;

      public MyHttpHandler(IHttpHandler originalHandler)
      {
         OriginalHandler = originalHandler;
      }

      public void ProcessRequest(HttpContext context)
      {
         // do not worry, ProcessRequest() will not be called, but let's be safe
         throw new InvalidOperationException("MyHttpHandler cannot process requests.");
      }

      public bool IsReusable
      {
         // IsReusable must be set to false since class has a member!
         get { return false; }
      }
   }
}
Ravi
  • 853
  • 8
  • 17
  • Ravi: Not lucky, Actually I tried this before. same exception `System.Web.HttpException: Session state is not available in this context.` – Nayana Adassuriya Jan 16 '14 at 07:46
0

Found the reason.

If is because AcquireRequestState trigger for the all files such as CSS, JS, images. those files are not having session.

solution: Seems there is a way to avoid calling IHttpModule for all the request. ckeck this answer JS,Images and CSS getting intercepted by HTTPModule.

But it didn't work for me. So I uses HttpContext.Current.Session instead of HttpApplication.Session and every time it checks if Session is null before save to session.

If some one knows, How to avoid calling IHttpModule for files other than .aspx Please help here.

Here is the final code

using System;
using System.Web;

public class Globalizer : IHttpModule
{    
  public void Init(HttpApplication context)
  {
    context.AcquireRequestState += new EventHandler(setLanguage);
  }

  public void Dispose(){}

  public void setLanguage(Object sender, EventArgs i_eventArgs)
  {
    if(HttpContext.Current.Session != null){
      HttpContext.Current.Session["language"] = "test";
    }

  }
}

Edit: One other way is only use session if request comes to a .aspx file

HttpApplication http_application = sender as HttpApplication; 
HttpContext context = http_application.Context;
if(Path.GetExtension(context.Request.PhysicalPath) == ".aspx")
{
 HttpContext.Current.Session["language"] = "test";
 http_application.Session["language2"] = "test2";
} 
Community
  • 1
  • 1
Nayana Adassuriya
  • 23,596
  • 30
  • 104
  • 147