Wednesday, January 14, 2009

Session state is not available in the current context

So you did some work in an ASP.Net web site and then you decided to or to add the Ajax extensions to it or switch to ASP.Net 3.5 or whatever and suddenly you get Ajax errors like "Sys is undefined" or you don't see images and the css files are not loaded. And after googling like crazy and finding a zillion possible solutions you decide to enter in the browser address bar the url of the offending image, css file or even ScriptResource.axd files containing the ajax javascript and you see a beautiful ASP.Net error page displaying "Session state is not available in this context.". Huh?

There are some reasons why this might happen, but let's examine the one that actually prompted me to write the article. Someone made a change in global.asax, trying to work with Session there, more precisely in the Application_AcquireRequestState event. The error was returned by the Session property of the HttpApplication object, the one that the global.asax file represents! In fact, this error can only be thrown from there in the current ASP.Net implementations.

First mistake: there was a Session property available in the HttpApplication object and it was immediately assumed that it is the same as Page.Session or HttpContext.Current.Session. It is about the same, except it throws an error if the underlying Session object is null.

Ok, but why is Session null? You are a smart .Net developer and you know that the Session should be available in that event. Any documentation says so! Yes, but it applies to your page, not to all the IHttpHandler implementations, like ScriptResource.axd! Also, the css and image problems occured for me only when opening the site in Cassini, not in IIS, so maybe it opens separate threads to load those resources and ignores the session or something similar, at least at that level.

Well, how does one fix it? Adding in global.asax a condition on Session not being null throws the same error, so you have to add it on HttpContext.Current.Session. In other words:
if (HttpContext.Current.Session!=null) //do stuff with sessions

Maybe this problem occurs in other places as well, but only the Session property of the HttpApplication will throw the "Session state is not available in this context." error.


Anonymous said...

Good Post. You saved my life:)

Nil said...

Thanks a lot man :)

You are savior!!

I was using it in Application_Error but it was throwing the same error.

Original error was Filepath doesn't exist and it was trying to refer Css in themes in subdirectory of my webapplication while App_Themes contains all the themes with CSS. I am clueless why it happened. I guess .axd file call must be causing that error.

Keep Posting!! :)

vapcguy said...

What if HttpContext.Current.Session IS null, which would be the case in anything separated from "the page" (System.Web.UI.Page, or Page page = this.Page()) - as in when you create additional classes to try and keep your Default.aspx.cs from growing unwieldy, but you still want to use session state there. You end up getting the error that titles your blog. How do you instantiate a "page" context to allow the code in additional classes to all use the same session? Or is that even possible?


Siderite said...

The error this post talks about occurs only when using the HttpApplication.Session property if the underlying Session object is null. Use the underlying HttpContext.Current.Session instead to be able to test if the session is null or not without getting an error.

As for the situations when session is null, Session is initialized in HttpContext's Session getter IF the SessionStateModule is not null and it gets instantiated in the Request AcquireState phase.

If you use a web service or an http handler, check Session is enabled (both in web config and in the various decorating attributes that define web services session rights)

It is possible to have HttpContext not null and Session null in some specific cases:

Also, I drilled down to this method: SessionStateUtility.AddHttpSessionStateToContext(HttpContext context, IHttpSessionState container) which seems to allow you to add an IHttpSessionState object of your own, if you choose to.

vapcguy said...

Great response. I did find that HttpContext.Current.Session["myVariable"] should not be null as long as it was instantiated in the function that called it (i.e. a button_onclick() method or whatever) as Session["myVariable"]. My problem was I assumed by instantiating the variable in the Page_Load that I was ok. Apparently that wasn't so, for me.


Stephen M. Redd said...

Thank you! The difference between HttpApplication.Session and HttpContext.Session is quite counter-intuitive. This article saved me a lot of pain trying to troubleshoot an HttpModule.

Le Pilot said...

Thank you very much! I only checked Session!=null and got the error. But with HttpContext.Current.Session!=null everything works fine.

Anonymous said...

Thank you! I had the same issue when I changed Framework version from 2.0 to 4.0. In 2.0 everything worked, but in 4.0 I needed to apply your advice.