HttpContext.Current.Session is null when routing requests

Without routing, HttpContext.Current.Session is there so I know that the StateServer is working. When I route my requests, HttpContext.Current.Session is null in the routed page. I am using .NET 3.5 sp1 on IIS 7.0, without the MVC previews. It appears that AcquireRequestState is never fired when using the routes and so the session variable isn’t instantiated/filled.

When I try to access the Session variables, I get this error:

base {System.Runtime.InteropServices.ExternalException} = {"Session state can only be used when enableSessionState is set to true, either in a configuration file or in the Page directive. Please also make sure that System.Web.SessionStateModule or a custom session state module is included in the <configuration>.

While debugging, I also get the error that the HttpContext.Current.Session is not accessible in that context.

My web.config looks like this:

<configuration>
  ...
  <system.web>
    <pages enableSessionState="true">
      <controls>
        ...
      </controls>
    </pages>
    ...
  </system.web>
  <sessionState cookieless="AutoDetect" mode="StateServer" timeout="22" />
  ...
</configuration>

Here’s the IRouteHandler implementation:

public class WebPageRouteHandler : IRouteHandler, IRequiresSessionState
{
    public string m_VirtualPath { get; private set; }
    public bool m_CheckPhysicalUrlAccess { get; set; }

    public WebPageRouteHandler(string virtualPath) : this(virtualPath, false)
    {
    }
    public WebPageRouteHandler(string virtualPath, bool checkPhysicalUrlAccess)
    {
        m_VirtualPath = virtualPath;
        m_CheckPhysicalUrlAccess = checkPhysicalUrlAccess;
    }

    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        if (m_CheckPhysicalUrlAccess
            && !UrlAuthorizationModule.CheckUrlAccessForPrincipal(
                   m_VirtualPath,
                   requestContext.HttpContext.User,
                   requestContext.HttpContext.Request.HttpMethod))
        {
            throw new SecurityException();
        }

        string var = String.Empty;
        foreach (var value in requestContext.RouteData.Values)
        {
            requestContext.HttpContext.Items[value.Key] = value.Value;
        }

        Page page = BuildManager.CreateInstanceFromVirtualPath(
                        m_VirtualPath, 
                        typeof(Page)) as Page;// IHttpHandler;

        if (page != null)
        {
            return page;
        }
        return page;
    }
}

I’ve also tried to put EnableSessionState="True" on the top of the aspx pages but still, nothing.

Any insights? Should I write another HttpRequestHandler that implements IRequiresSessionState?

Thanks.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Got it. Quite stupid, actually. It worked after I removed & added the SessionStateModule like so:

<configuration>
  ...
  <system.webServer>
    ...
    <modules>
      <remove name="Session" />
      <add name="Session" type="System.Web.SessionState.SessionStateModule"/>
      ...
    </modules>
  </system.webServer>
</configuration>

Simply adding it won’t work since “Session” should have already been defined in the machine.config.

Now, I wonder if that is the usual thing to do. It surely doesn’t seem so since it seems so crude…

Method 2

Just add attribute runAllManagedModulesForAllRequests="true" to system.webServermodules in web.config.

This attribute is enabled by default in MVC and Dynamic Data projects.

Method 3

runAllManagedModulesForAllRequests=true is actually a real bad solution. This increased the load time of my application by 200%. The better solution is to manually remove and add the session object and to avoid the run all managed modules attribute all together.

Method 4

None of these solutions worked for me. I added the following method into global.asax.cs then Session was not null:

protected void Application_PostAuthorizeRequest()
{
    HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
}

Method 5

What @Bogdan Maxim said. Or change to use InProc if you’re not using an external sesssion state server.

<sessionState mode="InProc" timeout="20" cookieless="AutoDetect" />

Look here for more info on the SessionState directive.

Method 6

Nice job! I’ve been having the exact same problem. Adding and removing the Session module worked perfectly for me too. It didn’t however bring back by HttpContext.Current.User so I tried your little trick with the FormsAuth module and sure enough, that did it.

<remove name="FormsAuthentication" />
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule"/>

Method 7

It seems that you have forgotten to add your state server address in the config file.

 <sessionstate mode="StateServer" timeout="20" server="127.0.0.1" port="42424" />

Method 8

The config section seems sound as it works if when pages are accessed normally. I’ve tried the other configurations suggested but the problem is still there.

I doubt the problem is in the Session provider since it works without the routing.

Method 9

I think this part of code make changes to the context.

 Page page = BuildManager.CreateInstanceFromVirtualPath(
                        m_VirtualPath, 
                        typeof(Page)) as Page;// IHttpHandler;

Also this part of code is useless:

 if (page != null)
 {
     return page;
 }
 return page;

It will always return the page wither it’s null or not.

Method 10

I was missing a reference to System.web.mvc dll in the session adapter, and adding the same fixed the issue.

Hopefully it will help someone else going through same scenario.

Method 11

a better solution is

runAllManagedModulesForAllRequest is a clever thing to do respect removing and resinserting session module.

alk.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x