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.