Using Session in ASP.NET

Recently I encounter some problems while using Session in my ASP.NET web application project. Although most of the problems have been solved, there are still rooms of improvement to gain more stability because it should be stable enough to use for real-world high-load business transactions.

Before working on the future improvement, I would like to write down stuff that I learnt from the project as well as interesting and useful articles that I found so that I can share them with my friends.

By the way, the project is basically about building an online shop that sells anime products, for example anime key chains. Also, there would be white-label service available. This means that we use the same website for other local anime shops to re-brand the website so that it appears as if they made it. Thus, the way I differentiate between the sources of transaction is using Session variables.

Phone_Strap

From my anime product collection: A phone strap featuring Saya Tokido from Little Busters! EX.

Why Session State?

HTTP is a stateless protocol, as we all know. Thus, we can’t store client information on a page. Nowadays, there is a newly available option that allows us to work against stateless nature of HTTP. It is the HTML5 Web Storage. However, personally I don’t like to spend time on figuring how to make my web application to be backwards compatible.

One of the main reasons why I choose to use Session State is because it is extremely easy to implement and any type of object can be stored in the Session. For example, I can just throw the entire online shopping cart into one Session variable easily with just one line of code.

Session["dsCart"] = new ShoppingCart(); // Store the shopping cart into Session

In addition, Session State is secure and the actual state is hidden from the client because it is stored on the server side.

Problem with Safari + Iframe

The way I do white-label website is that I provide the URL of the web application homepage to the anime shops. What they need to do is just embedding it in an iframe.

Everything worked fine until we realized that it did not work in Safari. The reason is because Safari has enforced its cookie policy with 5.1.4. By default, Safari blocks cookies from third parties and advertisers. But wait… Why should I care about the cookie policy when I am just using Session State?

Safari - Privacy Settings

By default, Safari blocks all cookies coming from third parties.

The reason is very simple. The Session State relies on the cookies. Of course, there are cookieless sessions available and cookieless sessions are there because users may have disabled the cookies on their browsers. However, cookieless session has a security problem because it makes the session ID easier to be retrieved.

In fact, IE9 has the same problem as well. The Privacy Settings in IE9 is by default set to “Medium” where all third-party cookies are blocked. However, due to the fact that only those which do not have a compact privacy policy will be blocked, I can easily solve it by having IIS to send a compact policy in HTTP header.

IE9 Privacy Settings

IE9 Privacy Setting is set to Medium, by default.

For Safari, having a compact policy does not help at all. Safari can no longer be tricked with that since the release of version 5.1.4. Fortunately (or maybe unfortunately), there are some (ugly) ways to solve the problem. For example, the one I found on StackOverflow is using JavaScript to open a new window to set a cookie for the domain (used in iframe). I do not like this solution very much. However, so far, I have not found any better way yet. So, no choice, I have to continue using it.

Session Timeout Issue

Another problem that I encountered in this project is the session timeout. If our customer does not refresh or make a server request by clicking on a button, for example, within a certain period of time (usually it is 20 minutes), then the sessions will end. Hence, we will loss all the information stored in the Session variables, including the shopping cart. Even worse, part of the system will just not work because Session variables are now all storing null value.

Hence, in the CodeBehind of all the web pages, I have this method, ShowSessionTimeoutMessage(), which takes in the Session State object as parameter and returns a JavaScript code which will be taken care by ScriptManager.RegisterClientScriptBlock. What it does is basically just prevent user from using the system once the Session has ended. This is to avoid the null reference errors in the application when the Session variables are all null. Also, it will show a message telling the user to start his/her online purchase from the first page again.

public static string ShowSessionTimeoutMessage(System.Web.SessionState.HttpSessionState session)
{
    string msgSession = "Your Session Has Timed Out";

    // Time to block GUI, 10 seconds before session ends
    int int_MilliSecondsTimeReminder = (session.Timeout * 60000) - 10000;

    return @"
        var myTimeReminder; 
        clearTimeout(myTimeReminder);
        var sessionTimeReminder = " + int_MilliSecondsTimeReminder.ToString() + @";
        function doReminder(){ $.blockUI({ message: '" + msgSession + @"' , 
        css: {border: 'none', padding: '15px', backgroundColor: '#000', '-webkit-border-radius': '10px', 
        '-moz-border-radius': '10px', opacity: .5, color: '#fff', 'text-align': 'left', cursor: 'default', 
        top: ($(window).height() - 600) /2 + 'px', left: ($(window).width() - 600) /2 + 'px', width: '600px' }
        }); }
        myTimeReminder=setTimeout('doReminder()', sessionTimeReminder);";
}

Here, I am using the jQuery BlockUI  plugin from M. Alsup to prevent user from interacting with the web application after Session ends.

Future Work

Personally, I do not like how I solve the Safari cookie policy problem. Thus, I will be finding better ways to solve it in the future. Also, if possible, I will try to make my entire ASP.NET web application to not use Session variables at all. Then I will not have all the problems mentioned above. Ah-ha!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s