ASP.NET C# Visitor Real-time Session Tracker

Tracking real-time online visitors on your website has been a challenge for
some time, here I will show you how to track online visitor in with ASP.NET C#,
in which will have the following features that I like to show you;

  1. SessionID – from the HttpSessionState object
  2. Path – the Virtual path of that visitor
  3. Username – Username of that authenticated user from System.Web.Security
  4. PageView – number of page that the visitor have viewed in your website

Our Tracker namespace is that heart of our visitors tracking magnesium, it
hold the SessionID, Virtual path, Username, and page view of all visitors. That
SesssionTrack is a static class, which is hold information of each session
through the session id of the user HttpSesstionState instance.

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections;

/// <summary>
/// Summary description for Tracker
/// Author:     Sarin Na Wangkanai
/// Website:    http://www.sarin.mobi/
/// License:    GPL
/// </summary>
namespace Sathai.Net.Tracker
{
    public static class SessionTrack
    {
        public static ArrayList States = new ArrayList();

        static SessionTrack() { }

        public static void Add(StateCollection state)
        {
            int StateIndex = Index(state);
            if (StateIndex < 0)
                States.Add(state);
            else
            {
                int PageView = ((StateCollection)States[StateIndex]).PageView;
                States[StateIndex] = state;
                ((StateCollection)States[StateIndex]).PageView = PageView + 1;
            }
        }

        public static void Remove(StateCollection state)
        {
            int StateIndex = Index(state);
            if (StateIndex >= 0)
                States.RemoveAt(StateIndex);
        }

        private static int Index(StateCollection state)
        {
            for (int i = 0; i < States.Count; i++)
                if (((StateCollection)States[i]).SessionID == state.SessionID)
                    return i;
            return -1;
        }
    }

    public class StateCollection
    {
        private string _sessionId;
        private string _path;
        private string _username;
        private int _pageview = 1;

        public string SessionID { get { return _sessionId; } set { _sessionId = value; } }
        public string Path { get { return _path; } set { _path = value; } }
        public string Username { get { return _username; } set { _username = value; } }
        public int PageView { get { return _pageview; } set { _pageview = value; } }
    }
}

Here I use a Master Page to add each user session to the SessionTrack class

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
using Sathai.Net.Tracker;

public partial class Page : System.Web.UI.MasterPage
{
    protected void Page_Load(object sender, EventArgs e)
    {
        SessionTrack.Add(new StateCollection() { SessionID = Session.SessionID, Path = Request.CurrentExecutionFilePath, Username = Page.User.Identity.Name });
        LabelSession.Text = Session.SessionID;
    }
}

Also in the Page.master html content page, I made that the visitor can see
the menu which pull from the web.sitemap and show the login status, if not
authenticated, the user will be able to redirect to the login page. Also the
master page will show that session id of that his/her is using.

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="Page.master.cs" Inherits="Page" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Tracker MasterPage</title>
    <asp:ContentPlaceHolder id="head" runat="server">
    </asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">
<div>
        <asp:Menu ID="Menu1" runat="server" DataSourceID="SiteMapDataSource1"
            Orientation="Horizontal" StaticDisplayLevels="2" BackColor="#F7F6F3"
            DynamicHorizontalOffset="2" Font-Names="Verdana" Font-Size="0.8em"
            ForeColor="#7C6F57" StaticSubMenuIndent="10px">
            <StaticSelectedStyle BackColor="#5D7B9D" />
            <StaticMenuItemStyle HorizontalPadding="5px" VerticalPadding="2px" />
            <DynamicHoverStyle BackColor="#7C6F57" ForeColor="White" />
            <DynamicMenuStyle BackColor="#F7F6F3" />
            <DynamicSelectedStyle BackColor="#5D7B9D" />
            <DynamicMenuItemStyle HorizontalPadding="5px" VerticalPadding="2px" />
            <StaticHoverStyle BackColor="#7C6F57" ForeColor="White" />
        </asp:Menu>
        <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" />
<hr />

        <asp:SiteMapPath ID="SiteMapPath1" runat="server" Font-Names="Verdana"
            Font-Size="0.8em" PathSeparator=" : ">
            <PathSeparatorStyle Font-Bold="True" ForeColor="#5D7B9D" />
            <CurrentNodeStyle ForeColor="#333333" />
            <NodeStyle Font-Bold="True" ForeColor="#7C6F57" />
            <RootNodeStyle Font-Bold="True" ForeColor="#5D7B9D" />
        </asp:SiteMapPath>
<hr />

        <asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">

        </asp:ContentPlaceHolder>
<hr />

        <asp:Label ID="LabelSession" runat="server" Text="Session:"></asp:Label>

        <asp:LoginView ID="LoginView1" runat="server">
            <LoggedInTemplate>
                 Username:
                <asp:LoginName ID="LoginName1" runat="server" />
            </LoggedInTemplate>
        </asp:LoginView>

        <asp:LoginStatus ID="LoginStatus1" runat="server" />
    </div>
</form>

</body>
</html>

And in order to use the FormAuthentication class build into ASP.NET you would
need to modify the web.config file

    <authentication mode="Forms">
<forms defaultUrl="Default.aspx" loginUrl="Login.aspx">
        <credentials passwordFormat="Clear">
          <user name="admin" password="password" />
        </credentials>
      </forms>
    </authentication>

Now to let the user be able to authenticate, you will need to create the
login.aspx page

<%@ Page Language="C#" MasterPageFile="~/Page.master" AutoEventWireup="true" CodeFile="Login.aspx.cs" Inherits="Login" Title="Login" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
    <asp:Login ID="Login1" runat="server" onauthenticate="Login1_Authenticate">
    </asp:Login>
</asp:Content>

Also when you double click on the login form in Visual Studio, you will be
brought to the code behide. Enter the authentication magnesium.

public partial class Login : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)
    {
        if (FormsAuthentication.Authenticate(Login1.UserName, Login1.Password))
            FormsAuthentication.RedirectFromLoginPage(Login1.UserName, Login1.RememberMeSet);
    }
}

Also in order to let the SessionTrack know when a visitor session has expire
(left the site), and the session id should be removed. Create a global.asax with
following codes;

<%@ Application Language="C#" %>
<%@ Import Namespace="Sathai.Net.Tracker" %>

<script runat="server">

    void Application_Start(object sender, EventArgs e)
    {
        // Code that runs on application startup
    }

    void Application_End(object sender, EventArgs e)
    {
        //  Code that runs on application shutdown
    }

    void Application_Error(object sender, EventArgs e)
    {
        // Code that runs when an unhandled error occurs

    }

    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.
        SessionTrack.Remove(new StateCollection() { SessionID = Session.SessionID });
    }

</script>

Now for you to the real time online visitor, you will need an admin page.
Here I created the content page;

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Admin.aspx.cs" Inherits="Admin" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Tracker Admin</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h3>Tracker Admin</h3>

        <a href="Default.aspx">Home</a>
        <asp:Label ID="LabelSessionTotal" runat="server" Text="Visitors: "></asp:Label>
<hr />

<table>
<tr>
<td style="width:200px;">SessionID</td>
<td style="width:100px;">Username</td>
<td style="width:100px;">PageView</td>
<td style="width:300px;">Path</td>
</tr>

        <asp:Repeater ID="Repeater1" runat="server">
            <ItemTemplate>
<tr>
<td><%# DataBinder.Eval(Container.DataItem,"SessionID") %></td>
<td><%# DataBinder.Eval(Container.DataItem, "Username")%></td>
<td><%# DataBinder.Eval(Container.DataItem, "PageView")%></td>
<td><%# DataBinder.Eval(Container.DataItem, "Path")%></td>
</tr>

            </ItemTemplate>
        </asp:Repeater>
        </table>
</div>
</form>

</body>
</html>

Also here is the code behide, where your data will bind to a repeater;

public partial class Admin : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        LabelSessionTotal.Text += Sathai.Net.Tracker.SessionTrack.States.Count;

        Repeater1.DataSource = Sathai.Net.Tracker.SessionTrack.States;
        Repeater1.DataBind();
    }
}

Open a few pages in a difference browser, even try login to your website to
see how it works. I will show you a preview page of my admin.

Tracker Admin

As you can see that our web admin show us the session id of each visitor,
username if he/she is authenticated, number page view that they have viewed, and
also the virtual path of the page content that he/she is visiting right now.

Tracker Project

This project has been long and details. Therefore I upload that zip of the
project for you study.

Download Session Tracker Version 1.1

I hope that post has been informative to you. Please comment or provide any
suggestion that you may have.


Kick It on DotNetKicks.com

  • http://www.svarga.biz Dmitry

    Good stuff,
    Thanks!


    Dmitry Svarga

  • Pingback: ASP.NET C# Visitor Real-time Session Tracker | Sarin.Mobi - ASP.NET

  • panos

    I implemented this on my production site and something occurred yesterday. I don’t know what but i received 250.000 emails with that error :

    Message:
    Object reference not set to an instance of an object.

    StackTrace
    at mySessionNetTracker.SessionTrack.Index(StateCollection state) in d:\ApplicationForms\WebSite\App_Code\SessionsTracker.cs:line 34 at mySessionNetTracker.SessionTrack.Add(StateCollection state) in d:\ApplicationForms\WebSite\App_Code\SessionsTracker.cs:line 15 at MasterForm.Page_Load(Object sender, EventArgs e) in d:\ApplicationForms\WebSite\MasterForm.master.cs:line 14 at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) at System.Web.UI.Control.OnLoad(EventArgs e) at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

    do you have any suggestion ?

  • http://www.sarin.mobi Sarin Na Wangkanai

    what is your production server sessionState set to? look in the Web.Config file.

    Refer http://msdn.microsoft.com/en-us/library/h6bb9cz9.aspx

    Try configure this setting to see which one work you :)

  • panos

    my sessionState is InProc

  • http://www.sarin.mobi Sarin Na Wangkanai

    umm, is it working your development computer? how much you change in the Tracker.cs class file? it look like that you havn’t call new ArrayList(); for “States” object yet.

  • http://www.vsoft.in Sankar

    Can you help me ho to detect the visitor’s system configuration through asp/asp.net programming.

  • http://www.sarin.mobi Sarin Na Wangkanai

    I think i don’t understand your question there mate :|

  • http://www.thabettech.blogspot.com/ Mohammed Thabet Zaky

    Hi Sarin,

    I want to thank you for the great & professional solution that enable at least me to solve many problems
    1-Online Users
    2-What user browse

    I appreciate this good work
    well done

    Best regards,

    Mohammed Thabet Zaky
    Cairo,Egypt
    SW Devekoper

  • http://www.sarin.mobi Sarin Na Wangkanai

    Your welcome! Mohammed, happy to help out.

  • http://www.real-skill.co.uk James Diaz

    Excellent code – well done
    I wish you put more comments because it’s hard for new programmers to understand.
    Thanks anyway.

  • Pingback: ASP.NET C# Visitor Real-time Session Tracker « Site Super Tracker

  • Ash_garagedog

    Big props!
    Peace

  • J Collier

    Would you fucking learn English before posting in it?  The following
    is gibberish: 

      “Our Tracker namespace is that heart of our visitors tracking magnesium, it
      
    hold the SessionID, Virtual path, Username, and page view of all visitors.”

    What you have done is copy another person’s Web site.

  • http://www.sarin.mobi/ sathai

    Fuck off! Being an ass wouldn’t get you anywhere. i’m not a native speaker, and a correction would have gain a kind thank you. but now you can go fuck yourself shit head and go an died in your arrogance.