Showing posts with label Session. Show all posts
Showing posts with label Session. Show all posts

Monday, 22 February 2010

ASP.NET Session lost after Response.Redirect problem? You may just need to clear your cookies.

If you develop in ASP.NET soon or later you have come across a very annoying problem: the Session is lost after a Response.Redirect.

This is a such random problem that puzzled me and my colleagues in several occasions for quite long time.

Let's take for example the following snippet:


Session.Add("UserID", 1234);
Response.Redirect("/default.aspx", false);

This is adding the value 1234 to the UserID Session variable and then redirects the request to the default.aspx page. Note that the false parameter indicates that the Response should not end abruptly, instead the redirect will occur after the Page life cycle has loaded completely.
Bertrand Le Roy's article explains very well the reason why this is wise to do and I suggest you to read it if you haven't done yet.

So if you are still having the Session problem despite you are allowing the entire Page life cycle to load, then probably the problem may be much simpler than you think!


Basically the problem may well be related with the browser's cookies. In fact clearing you cookies may solve it!


Cookies are the mean by which a session can persist across different requests, the browser is identified each time through the session ID stored in a cookie.

I didn't have time to investigate what is exactly occurring, I'll spare this for next time when I'll update this post.

Friday, 12 February 2010

Singleton pattern in ASP.NET applications

  
Some years ago I remember I spent quite some time while trying to debug a cross session contamination of data.

The problem ended up being due to an improper use of the static modifier in the context of ASP.NET applications.

In fact, in ASP.NET,  static objects are instantiated one time for each application domain, and all processing in the application share the same object, while at that time I understood that the static modifier acted within the page life span!

For this very reason, a Singleton pattern that relies on a static object will be most of the times useless if the wished behaviour is to have its life span limited to the page life cycle: a static object is always shared across the entire application!

In my own experience, when I require a single instance of an object I most often want its scope and life cycle to be within a web request or single session and in very few occasions to be application wide.

I decided I was going to create a helper class that would allow me to instantiate a Singleton instance of an object and being able to decide its scope.

I put together a Singleton helper class and 3 persister classes: one for the Session, one for the Page life cycle and one for the Application.

The persister classes would define the singleton life span and scope so that if I wanted to have a single instance of MyObjectClass with a life span of a single web request I could easily get an instance of it in the following way:

MyObjectClass o = Singleton<MyObjectClass, ItemsPersister>.GetInstance();

Likewise within the session life span:

MyObjectClass o = Singleton<MyObjectClass, SessionPersister>.GetInstance();

And application life span:

MyObjectClass o = Singleton<MyObjectClass, ApplicationPersister>.GetInstance();
The Singleton<T, S> has T which is the type of the class I want to have a single instance of, and S the type of the Persister that I wish to adopt.

Here is the singleton helper and the persisters full code:

    public class Singleton<T, S> : ISingleton
        where T : new()
        where S : IPersister, new()
    {
        public static T GetInstance()
        {
            var identifier = new T().GetType().Name;
            var persister = new S();
            var instance = (T)persister.Get(identifier);
            if (instance == null)
            {
                instance = new T();
                persister.Set(identifier, instance);
            }
            return (T)instance;
        }
    }

    public interface IPersister
    {
        object Get(string name);
        void Set(string name, object o);
        void Remove(string name);
    }

    public class SessionPersister : IPersister
    {
        private HttpContext _Context;

        public SessionPersister()
        {
            this._Context = HttpContext.Current;
        }

        public object Get(string name)
        {
            return this._Context.Session[name];
        }

        public void Set(string name, object o)
        {
            this._Context.Session.Add(name, o);
        }

        public void Remove(string name)
        {
            this._Context.Session.Remove(name);
        }
    }

    public class ItemsPersister : IPersister
    {
        private HttpContext _Context;

        public ItemsPersister()
        {
            this._Context = HttpContext.Current;
        }

        public object Get(string name)
        {
            return this._Context.Items[name];
        }

        public void Set(string name, object o)
        {
            this._Context.Items.Add(name, o);
        }

        public void Remove(string name)
        {
            this._Context.Items.Remove(name);
        }
    }

    public class ApplicationPersister : IPersister
    {
        private HttpContext _Context;

        public ApplicationPersister()
        {
            this._Context = HttpContext.Current;
        }
        public object Get(string name)
        {
            return this._Context.Application[name];
        }

        public void Set(string name, object o)
        {
            this._Context.Application.Add(name, o);
        }

        public void Remove(string name)
        {
            this._Context.Application.Remove(name);
        }
    }

Please note that my solution is forcing a bit the concept of Singleton pattern. This pattern generally has the class that we want a single instance of, responsible for generating its own instance; this class also has only private constructors to guarantee that an instance of it can be created only within itself.

My main aim was not to reinvent the Singleton pattern but to provide a simple way of creating a single instance of a class within a chosen life scope.

If you are not familiar with the Singleton pattern please refer to http://en.wikipedia.org/wiki/Singleton_pattern for a more in depth explanation of the Singleton pattern.

Thanks for reading.