12

I have a WebSite with a custom Cache object inside a class library. All of the projects are running .NET 3.5. I would like to convert this class to use Session state instead of cache, in order to preserve state in a stateserver when my application recycles. However this code throws an exception with "HttpContext.Current.Session is null" when I visit the methods from my Global.asax file. I call the class like this:

Customer customer = CustomerCache.Instance.GetCustomer(authTicket.UserData);

Why is the object allways null?

public class CustomerCache: System.Web.SessionState.IRequiresSessionState
{
    private static CustomerCache m_instance;

    private static Cache m_cache = HttpContext.Current.Cache;

    private CustomerCache()
    {
    }

    public static CustomerCache Instance
    {
        get
        {
            if ( m_instance == null )
                m_instance = new CustomerCache();

            return m_instance;
        }
    }

    public void AddCustomer( string key, Customer customer )
    {
        HttpContext.Current.Session[key] = customer;

        m_cache.Insert( key, customer, null, Cache.NoAbsoluteExpiration, new TimeSpan( 0, 20, 0 ), CacheItemPriority.NotRemovable, null );
    }

    public Customer GetCustomer( string key )
    {
        object test = HttpContext.Current.Session[ key ];

        return m_cache[ key ] as Customer;
    }
}

As you can see I've tried to add IRequiresSessionState to the class but that doesn't make a difference.

Cheers Jens

M Raymaker
  • 1,231
  • 5
  • 14
  • 31
  • If you try to access the session from Application_Start, there is no live Session yet. – onof May 03 '11 at 11:30

2 Answers2

18

It isn't really about including the State inside your class, but rather where you call it in your Global.asax. Session isn't available in all the methods.

A working example would be:

using System.Web.SessionState;

// ...

protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
    {
        if (Context.Handler is IRequiresSessionState || Context.Handler is IReadOnlySessionState)
        {
            HttpContext context = HttpContext.Current;
            // Your Methods
        }
    }

It will not work e.g. in Application_Start

robyaw
  • 2,274
  • 2
  • 22
  • 29
Dennis Röttger
  • 1,975
  • 6
  • 32
  • 51
  • I call it in void Application_AuthenticateRequest(object sender, EventArgs e), so that's a no go? – M Raymaker May 03 '11 at 11:48
  • Yup, that's a no go, when this Method is called the Session is always null, you can test it by simply debugging and checking whether `Context.Handler` is either `IRequiresSessionState` or `IReadOnlySessionState`, which is never the case. However, based on what I've done, `Application_PreRequestHandlerExecute` works for this, though I'm not sure about your goals. – Dennis Röttger May 03 '11 at 11:53
0

Depending on what you're trying to do, you may also benefit from using Session_Start and Session_End in Global.asax:

http://msdn.microsoft.com/en-us/library/ms178473(v=vs.100).aspx

http://msdn.microsoft.com/en-us/library/ms178581(v=vs.100).aspx

void Session_Start(object sender, EventArgs e)
{
    // Code that runs when a new session is started

}

void Session_End(object sender, EventArgs e)
{
    // Code that runs when a session ends. 
    // Note: The Session_End event is raised only when the sessionstate mode
    // is set to InProc in the Web.config file. If session mode is set to StateServer 
    // or SQLServer, the event is not raised.

}

Note the restrictions on SessionState Mode before relying on Session_End.

Amir Soofi
  • 386
  • 3
  • 3