For a naive implementation, you can use a custom HttpModule. For each request to your application, you'd:
- Check if Request.Cookies includes a Tracking Cookie
- If the tracking cookie doesn't exist, this is probably a new visitor (or else, their cookie has expired -- see 4.)
- For a new visitor, log the visitor stats, then update the visitor count
- Add the tracking cookie to the response being sent back to the visitor. You'll want to set this cookie to have a rather long expiration period, so you don't get lots of "false-positives" with returning users whose cookies have expired.
Here's some skeleton code below (save as StatsCounter.cs):
using System;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Transactions;
namespace hitcounter
{
public class StatsCounter : IHttpModule
{
// This is what we'll call our tracking cookie.
// Alternatively, you could read this from your Web.config file:
public const string TrackingCookieName = "__SITE__STATS";
#region IHttpModule Members
public void Dispose()
{ ;}
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
context.PreSendRequestHeaders += new EventHandler(context_PreSendRequestHeaders);
}
void context_PreSendRequestHeaders(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
HttpResponse response = app.Response;
if (response.Cookies[TrackingCookieName] == null)
{
HttpCookie trackingCookie = new HttpCookie(TrackingCookieName);
trackingCookie.Expires = DateTime.Now.AddYears(1); // make this cookie last a while
trackingCookie.HttpOnly = true;
trackingCookie.Path = "/";
trackingCookie.Values["VisitorCount"] = GetVisitorCount().ToString();
trackingCookie.Values["LastVisit"] = DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss");
response.Cookies.Add(trackingCookie);
}
}
private long GetVisitorCount()
{
// Lookup visitor count and cache it, for improved performance.
// Return Count (we're returning 0 here since this is just a stub):
return 0;
}
void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
HttpRequest request = app.Request;
// Check for tracking cookie:
if (request.Cookies[TrackingCookieName] != null)
{
// Returning visitor...
}
else
{
// New visitor - record stats:
string userAgent = request.ServerVariables["HTTP_USER_AGENT"];
string ipAddress = request.ServerVariables["HTTP_REMOTE_IP"];
string time = DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss");
// ...
// Log visitor stats to database
TransactionOptions opts = new TransactionOptions();
opts.IsolationLevel = System.Transactions.IsolationLevel.Serializable;
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, opts))
{
// Update visitor count.
// Invalidate cached visitor count.
}
}
}
#endregion
}
}
Register this module by adding the following lines to your Web.config file:
<?xml version="1.0"?>
<configuration>
...
<system.web>
...
<httpModules>
<add name="StatsCounter" type="<ApplicationAssembly>.StatsCounter" />
</httpModules>
</system.web>
</configuration>
(Replace with the name of your web application project, or remove it if you're using a Website project.
Hopefully, this'll be enough to get you started experimenting. As others have pointed out though, for an actual site, you're much better off using Google (or some other) analytics solution for this.