2008/08/25

A simple Asp.Net Counter [2/25/2011 updated]

2/25/2011 Updated:
Added the Thread-Safe lock.

I create a very simple page counter for some purposes:
  1. It will store the counter data (visit times, last visit date) in a file for easy manipulation.
  2. If the file doesn't exist, then program should create it automatically.
  3. One file can store as many counters info as I want. It I have 5+ pages (or even the whole website) need to be counted, this file can store than all.
  4. Data should be read/wrote easily.
  5. The file should be read by other programs/software easily.
  6. The counter can be reset by program without editing the file manually.
I chose XML as my file format. Here is the code:
static object LockMe = new object();
public static string CounterInfo(string tag, bool resetCounter)
{
  lock (LockMe)
  {
    string counterValue = "1";

    try
    {
      bool tagNotFound = true;
      XmlDocument xDoc = new XmlDocument();
      string filename = @"~/CounterData.xml"; //file to store the counter value
      FileInfo oFile = new FileInfo(HttpContext.Current.Server.MapPath(
      filename));

      //create one if the file doesn't exist
      if (!file.Exists)
        xDoc.LoadXml("");
      else
      {
        //load file which contains counter info
        xDoc.Load(HttpContext.Current.Server.MapPath(filename));

        foreach (XmlNode node in xDoc.GetElementsByTagName(tag))
        {
          if (!resetCounter)
          {
            //show counter value
            counterValue = (Convert.ToInt16(node.InnerText) + 1).ToString();

            //update counter value
            node.InnerText = counterValue;
          }
          else
          {
            //set the value to zero
            node.InnerText = "0";
          }

          //update modified date
          node.Attributes["modifieddate"].Value = DateTime.Now.ToShortDateString();
          tagNotFound = false;
          break;
        }
      }

      //if we can't find the tag, then create one
      if (tagNotFound)
      {
        XmlElement elem = xdoc.CreateElement(tag);
        elem.SetAttribute("modifieddate", DateTime.Now.ToShortDateString());
        elem.InnerText = "1";
        xDoc.DocumentElement.AppendChild(elem);
        elem = null;
      }

      //save back to the xml file
      xDoc.Save(HttpContext.Current.Server.MapPath(filename));
      xDoc = null;
      oFile = null;
    }
    catch (Exception e)
    {
      //log your error message here
    }

    return counterValue;
  }
}