Introduction

This article explains how to track ASP.NET web pages through your own web application without relying on external tracking tools. This does not eliminate the need for external tools, but it gives some satisfaction to have your own tracking that you can play with and modify to suit to your business requirements. This is all possible due to the rich API provided by the .NET framework.

I researched on the web to find out if people have developed a code to do custom tracking in .NET, and I found an excellent article by Wayne Plourde that explains how to track web pages in ASP.NET. This article derives lots of inspiration from Wayne Plourde's original article. I recommend that you read this article first as it will help you to understand page tracking concepts.

When I ported Wayne Plourde's VB.NET code to C#, I stumbled upon a few problems regarding session state and the way it is being handled in .NET framework by Microsoft architects. I have been thinking for a long time to write on this subject and share my thoughts with the CodeProject community. Now I got an excellent opportunity to share my thoughts as I am switching jobs.

When I publicized my resume for a new job, I wanted to see real time usage of web page tracking methods. I was thrilled to see that people spend an average of 2-10 seconds to see a resume, and if it does not catch their attention, it is buried forever.

Location - Location - Location

As a web application developer, I am interested to know the location of the visitors coming to a web site. This is important from business standpoint to target your audience accordingly. In a simple scenario, I am interested to know the location of people accessing my resume just for the sake of curiosity.

There are some articles on CodeProject on geographical locations of the visitors based upon an IP address. I like GeoBytes as they provide free service for non-commercial use. GeoBytes provide a simple cut-and-paste code that you can put on your site to greet your users.

I want little more on this, as I need to store geographical location of the users based upon an IP address for statistical analysis on the pattern of visitors. Currently, GeoBytes does not provide a web-service like method in which you pass an IP address from your web server and it returns the geographical location. There is a little work-around to this.

Through the above startup HTML page, a trip is made to GeoBytes site and it returns the city, region, and country based upon an IP address in HTTP request. After this, we call our regular ASPX startup page and pass these three parameters as Request query string. Now you have the information, and use it to analyze or redirect the users to custom pages based upon their locations. For non-commercial use, this may be an acceptable solution, but for high volume sites, you need to have your own geo database.

For demo project to work on your machine, please make sure that you define index.html as a default document type through your inetmgr MMC.

Issues with Session State

If you are developing a scalable web application in ASP.NET, you will come across a need to switch your session state from InProc to either StateServer or SQLServer in the future. In my early stages of learning ASP.NET, we always used InProc session state, but later we had to change it to StateServer from scalability point of view. There is an excellent FAQ on Session State by Patrick Y. Ng in the ASP.NET site, and it is worth spending some time to read this article to get an idea about session state in detail.

If your application uses InProc session state, Wayne Plourde's article code is sufficient enough to do the page tracking. I had to do some changes in the concepts of web page tracking to accommodate StateServer session state, due to following major reasons:

Session_End event is not supported in StateServer or SQLServer Session mode.

Objects need to be serializable when using StateServer or SQLServer Session mode.

This article's code works for all three session states, and you can make this code a part of your own framework and enable page tracking by having a few entries in your web.config file.

ASP.NET Page Tracking

My purpose was not to invent how ASP.NET page tracking should be done. I was just trying to make Wayne's code work for all three session states. I have explained the changes that I had to make in order for it to work for the limitations explained above.

Simulate Session_End event in StateServer or SQLServer Session mode by creating a cache object with a hookup that will fire exactly on session time out.

This approach has its own caveat as the session objects will not be available when we simulate session_end event, as ASP.NET will recycle the session at that very moment when we were trying to access it.

We simulate the session object by creating a simple static hash table that will hold our objects until the session ends.

Basics of Wayne's Page Tracking

Create a Session Tracker class.

Persist this class in a ASP.NET Session.

Use cookies to store previous values of variables that we are interested to track.

Update the tracker class in Session whenever user visits a page.

Publish the data when session_start and session_end events fire.

Show a summary of Page Visited Statistics when session expires.

Modifications to Wayne's Page Tracking for All Three Session States

Create a modified Session Tracker Class.

Simulate a session_end event when session expires.

Persist this class in a static hash table in view of session_end event problem.

Global.asax v/s HttpModule

The global.asax.cs provides methods that execute on specific events. Each web application has its own global.asax.cs file, but it is my own personal taste not to use this file and instead use HTTP Module due to the following reasons:

Http Module can be used by many web applications that you develop.

There is no need to copy code from one global.asax web application to another web application when it is going to be same for all web applications.

Keep a common code in your own framework and use that framework all across your web applications.

Register your HttpModule

In the demo project, I have a small framework class library called EADFramework. EAD stands for Enterprise Application Development. Reference this class library in your web project. Modify web.config to register HttpModule and set parameters used by Page Tracking.

You can turn on/off site tracking by using SiteTracking value as "Full" or "None". In my own framework, I also use "Partial" tracking to track selected pages only. This itself is a separate topic for navigation to/from pages. I use a separate class for Page Navigation using attributes defined in web.config. One of the attributes for Page Navigation is PageVisit and when set on 'true', it turns page tracking on for that page. For the purpose of simplicity, I am not putting the code for partial web page tracking. I used the PageVisit method in PageTrackerUtil class to control partial page tracking.

You can specify ExcludeIPList to filter out your local or internal IPs for tracking. You could monitor one or more specific IP by using IncludeIPList. Use IncludeUserList and ExcludeUserList to list CSV of users that need to be monitored or excluded from monitoring.

The session state is defined as a StateServer. When you run this demo, please make sure that your ASP.NET State Service is running on your web server.

AcquireRequestState event - This event occurs when ASP.NET acquires the current session state associated with the current request. This is an ideal place to create a cache object with a callback function. This callback function timeout is set to session timeout limit.

The CacheRemoveCallBack method calls method PageTrackerUtil.TrackSessionEnd to publish statistics at the end of session. The CacheCallBackMethod is synchronized to execute at the same time when session expires.

Page Tracking Methods

Through above HttpModule, we have hooked up three methods: TrackSessionStart, TrackSessionPages, and TrackSessionEnd of PageTrackerUtil to take care of the page level tracking. Since we will not have access to the Session when it is recycled by ASP.NET, we will use our own small and simple static hash table to persist objects for page level tracking.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Share

About the Author

Vikram is an Enterprise Application Architect specializing in EAI, ETL, all relational databases and transforming legacy applications to Microsoft .Net environment. Vikram works for a consulting firm in Research Triangle Park, NC. Vikram has expertise in all relational databases, Cobol, mainframe, OO programming, C, Perl and Linux. C# is a newfound craze for Vikram.