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;
  }
}

Usage:
lbl_GuestBookCounter.Text = "This page has been visited "+ CounterInfo("GuestBook", false) + " times.";
A XML file will be created under the current application location (you can change the location), and the format will looks like:
<Counters>
<GuestBook modifieddate="8/22/2008">18</GuestBook>
<HomePage modifieddate="8/24/2008">57</HomePage>
</Counters>
You can add/remove information you want to store/delete to element attributes. If you want to reset the counter for a specific page, just use
CounterInfo("GuestBook", true);
You are free to copy and modify this code. Also, if you improve this poor code, please send me a copy. :)

4 comments:

  1. Hi. Thanks for the great counter example.

    On the local machine it works fine, but when I host the website i got the following error:
    ASP.NET is not authorized to access the requested resource. Consider granting access rights to the resource to the ASP.NET request identity. ASP.NET has a base process identity (typically {MACHINE}\ASPNET on IIS 5 or Network Service on IIS 6) that is used if the application is not impersonating. If the application is impersonating via identity impersonate="true"/, the identity will be the anonymous user (typically IUSR_MACHINENAME) or the authenticated request user.

    To grant ASP.NET access to a file, right-click the file in Explorer, choose "Properties" and select the Security tab. Click "Add" to add the appropriate user or group. Highlight the ASP.NET account, and check the boxes for the desired access.



    Is there a way to grant write access easily to this specified file. Thanks in advance.

    ReplyDelete
  2. The easiest way is to create a folder to contain log files like error log, counter log... etc.

    The folder which contains the log file need to set the permission properly. The "User" account musts have the "modify" privilege to that folder.
    Right click on that folder -> properties -> Security -> check the "Modify".

    After doing this, you don't have to worry about that error message anymore.

    Be careful about the security issue of that folder.

    ReplyDelete
  3. I absolutely love your blog and find many
    of your post's to be what precisely I'm looking for. can you offer guest writers to write content
    to suit your needs? I wouldn't mind writing a post or elaborating on a lot of the subjects you write with regards to here. Again, awesome blog!
    Look at my web blog - payday loans

    ReplyDelete
    Replies
    1. Hi Anonymous,

      The reason I deleted all of you replies is because they look like spam (according to the blog link that you provided). Any commercial ad that posted by visitors is not welcome here. Sorry.

      Delete