Master C# Logo banner
Welcome to MasterCSharp.com - Master C#, the easy way... - by Saurabh Nandu

 


XML Counter 2

Add Comment
 

 
Download File SDK
counter2.zip (7kb) Beta1

Introduction
Page Counter - Every web-master wants to know how many people and from where are visiting their pages (including Me) . A component without which any website is incomplete is a good Counter which helps the Web Developer to track the viewers and the viewers trend.
To meet this requirement I have developed a Counter in ASP.NET, since I have access only to free resources in have used XML as my database to store the visitor information. Although I am fully aware that if your site has high visitor count XML won't be a good database since the file size of the database file will run into Megabytes in the span of few hours. But you will find this example very useful to learn XML interaction in C#. 

Explanation
This example consists of 2 pages.
1) Counter.aspx - Contains the code to get the Viewer information and post it in a XML file. It uses the Class "System.Xml.XmlDocument" and the "System.Xml.XmlNavigator" to Read and Append information in a XML file.
XmlNavigator provides very easy ways to navigate through a Xml document. Also used are some other classes (like: HttpBrowserCapabilities) which help to get the user information.
2) viewcounter.aspx - Is a Administrator file. It uses the Class "System.Xml.XmlDataDocument" to get the viewer data from the XML file into a "System.Data.DataSet" object. After the a DataSet object is created then it is very easy to manipulate the Data to viewing purpose. In this example we use a "Repeater" to display the data in the DataSet. 

Requirements
1) .NET SDK beta1 (Note: This example might not run on future versions of the SDK).
2) ASP.NET hosting with appropriate permissions.

Xml Database Format

<?xml version="1.0" ?> 
  <Visitors>
    <total tot="172" /> 
    <Viewer>
      <Referrer>learncsharp.cjb.net</Referrer> 
      <UserAgent>Mozilla/4.0 </UserAgent> 
      <UserHostAddress>205.184.137.153</UserHostAddress> 
      <UserHostName>205.184.137.153</UserHostName> 
      <BrowserType>IE5</BrowserType> 
      <BrowserName>IE</BrowserName> 
      <MajorVersion>5</MajorVersion> 
      <MinorVersion>0.5</MinorVersion> 
      <Platform>Unknown</Platform> 
      <Date>01/10/2001</Date> 
      <Time>09:27</Time> 
    </Viewer>
  </Visitors>

Code
1) counter.aspx :- The Counter Page 

<%@ Import Namespace="System.IO" %>
<%@ Assembly Name="System.Xml" %>
<%@ Import Namespace="System.Xml" %>
<%@ page language="c#"  EnableSessionState="True" %>
<%-- These are the imported assemblies and namespaces
need to run the counter --%>
<html>
<head>
<title>Saurabh's XML Counter Script</title>
 <script language="C#" runat="server">
 //script is called when the page is loaded
 public void Page_Load(Object src, EventArgs e)
 {
   //the path to the Xml file which will contain all the data
   //modify this if you have any other file or directory mappings.
   //modify this if you have been directed here from Step 2 of the ReadMe file.
   string datafile="db/xmlcounter.xml" ;

   if(!Page.IsPostBack){
   //try-catch block containing the counter code
   try {
     //create an instance of the class XmlDocument
     XmlDocument xmldocument = new XmlDocument() ;

     //Open a FileStream to the specified file 
     FileStream fin ;
     //It is very Important to specify the "FileShare.ReadWrite" option.
     //This allows other viewers to also read and write to the Database
     //This was missing in my last release hence there was a BUG !!!
     fin = new FileStream(Server.MapPath(datafile), FileMode.Open,
		FileAccess.Read, FileShare.ReadWrite) ;
     //Load the Document
     xmldocument.Load(new StreamReader(fin)) ;
     fin.Close();
     //create an instance of the DocumentNavigator class used to
     //navigate through and XML file	
     DocumentNavigator navigator = new DocumentNavigator(xmldocument) ;

     //Move to the first element (in my file 'Visitors')
     navigator.MoveToDocumentElement() ;
     //move to it child at position '0' (ie.in my file 'total' node)
     navigator.MoveToChild(0) ;

     //check if we are on the right element which has an attribute
     if (navigator.HasAttributes) {
	//get the attribute of the node 'total' called 'tot'
	//since the value stored is in a string format we 'cast'
         //it into a Int type
	int total = int.Parse(navigator.GetAttribute("tot")) ;
	//increase the counter
	total++ ;
	//show the counter on the page
	countmess.Text = "You are visitor No: "+total.ToString() ;
	//save the incremented counter back in the XML file
	navigator.SetAttribute(0,total.ToString() );
     }

     //Update the Database only if a new session is there 		
     if(Session["counter"]==null)
     {
	//move back to the Document element
	navigator.MoveToDocumentElement() ;
	navigator.MoveToChild(0) ;
	//then insert the element after the 'total' element which will
	//contain all the information  of a single visitor 
  	navigator.Insert(TreePosition.After , XmlNodeType.Element,
		 "Viewer","","");
	//make an instance to the HttpUrl class to get information of the
	//referrer to the page if any. if there are no referrers then by
	//Default this object is 'null'
         //so we have to make a check if it is null and do the needful
	HttpUrl objUrl = Request.UrlReferrer;
	if(objUrl!=null)
	{
	  navigator.Insert(TreePosition.FirstChild, XmlNodeType.Element,
			"Referrer","","");
	  navigator.Insert(TreePosition.FirstChild, XmlNodeType.Text,
			"Referrer","","") ;
	  navigator.Value = objUrl.Host ;
	}
	else
	{
	  navigator.Insert(TreePosition.FirstChild, XmlNodeType.Element,
			"Referrer","","");
	  navigator.Insert(TreePosition.FirstChild, XmlNodeType.Text,
			"Referrer","","") ;
	  navigator.Value = "Direct" ;
	}
	//release the resource for Garbage collection	
	objUrl=null ;
	//move to parent node and then insert the information
 	//about the useragent
	navigator.MoveToParent() ;
	navigator.Insert(TreePosition.After, XmlNodeType.Element,
			"UserAgent","","" ) ;
	navigator.Insert(TreePosition.FirstChild, XmlNodeType.Text,
			"UserAgent","","" ) ;
	navigator.Value = Request.UserAgent ;
	navigator.MoveToParent() ;
	navigator.Insert(TreePosition.After, XmlNodeType.Element,
			"UserHostAddress","","" ) ;
	navigator.Insert(TreePosition.FirstChild, XmlNodeType.Text,
			"UserHostAddress","","" ) ;
	navigator.Value = Request.UserHostAddress ;
	navigator.MoveToParent() ;
	navigator.Insert(TreePosition.After, XmlNodeType.Element,
			"UserHostName","","" ) ;
	navigator.Insert(TreePosition.FirstChild, XmlNodeType.Text,
			"UserHostName","","" ) ;
	navigator.Value = Request.UserHostName ;
	//to get more information of the users browsers capabilities
	//make an object of the HttpBrowserCapabilities class
	HttpBrowserCapabilities bc = Request.Browser;

	navigator.MoveToParent() ;
	navigator.Insert(TreePosition.After, XmlNodeType.Element,
			"BrowserType","","" ) ;
	navigator.Insert(TreePosition.FirstChild, XmlNodeType.Text,
			"BrowserType","","" ) ;
	navigator.Value = bc.Type ;

	navigator.MoveToParent() ;
	navigator.Insert(TreePosition.After, XmlNodeType.Element,
			"BrowserName","","" ) ;
	navigator.Insert(TreePosition.FirstChild, XmlNodeType.Text,
			"BrowserName","","" ) ;
	navigator.Value = bc.Browser ;

	navigator.MoveToParent() ;
	navigator.Insert(TreePosition.After, XmlNodeType.Element,
			"MajorVersion","","" ) ;
	navigator.Insert(TreePosition.FirstChild, XmlNodeType.Text,
			"MajorVersion","","" ) ;
	navigator.Value = bc.MajorVersion.ToString() ;

	navigator.MoveToParent() ;
	navigator.Insert(TreePosition.After, XmlNodeType.Element,
			"MinorVersion","","" ) ;
	navigator.Insert(TreePosition.FirstChild, XmlNodeType.Text,
			"MinorVersion","","" ) ;
	navigator.Value = bc.MinorVersion.ToString(); ;

	navigator.MoveToParent() ;
	navigator.Insert(TreePosition.After, XmlNodeType.Element,
			"Platform","","" ) ;
	navigator.Insert(TreePosition.FirstChild, XmlNodeType.Text,
			"Platform","","" ) ;
	navigator.Value = bc.Platform ;

	//Make an object of the DateTime class to get the Date Time 
	DateTime now = DateTime.Now ;
	navigator.MoveToParent() ;
	navigator.Insert(TreePosition.After, XmlNodeType.Element,
			"Date","","" ) ;
	navigator.Insert(TreePosition.FirstChild, XmlNodeType.Text,
			"Date","","" ) ;
	navigator.Value = now.ToShortDateString() ;

	navigator.MoveToParent() ;
	navigator.Insert(TreePosition.After, XmlNodeType.Element,
			"Time","","" ) ;
	navigator.Insert(TreePosition.FirstChild, XmlNodeType.Text,
			"Time","","" ) ;
	navigator.Value = now.ToShortTimeString() ;
	//Create a File Stream again to Write to the Database
	//Again remember to specify the "FileShare.ReadWrite"
	FileStream fout ;
	fout = new FileStream(Server.MapPath(datafile), FileMode.Open,
		FileAccess.Write,FileShare.ReadWrite) ;

	//finally save the user data to the xml database file
	xmldocument.Save(new StreamWriter(fout)) ;
	//free the resources explicitly for other classes to use
	fout.Close();
	navigator=null ;
	xmldocument=null ;
	//Just store any value to the session 
	Session["counter"]=1 ;
      }

    }
    catch(Exception edd)
    {
      //catch other exceptions
      Response.Write("<font color=#FF0000>An Exception Occurred "
		+edd.ToString()+"</font>") ;
    }

  }
}

</script>
</head>

<body >

<h3 align="center">Welcome to Saurabh's Counter Script</h3>
<br>
<p align="center">
This is a sample page which has the counter scripting in it.
Take the script from this page and paste it on your page.

</p>
<asp:label text="You are visitor No: 0" style="font-size:28pt"
	id="countmess" runat="server" />
</body>
</html>

 

2) viewcounter.aspx : The counter information viewing page

<%@ Import Namespace="System" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Data" %>
<%@ Assembly Name="System.Xml" %>
<%@ Import Namespace="System.Xml" %>
<%@ Page Language="C#"  %>
<html>
<head>
<title>Saurabh's XML Counter Script</title>
  <script language="C#" runat=server>
   //this script is execute when the page is loaded
   public void Page_Load(Object sender, EventArgs e)
   {
     //the path to the Xml file which will contain all the data
     //modify this if you have any other file or directory mappings.
     string datafile="db/xmlcounter.xml" ;
     try
     {
	//Make an instance of the XmlDataDocument class which reads
	//data from a xml file and stores it in an DataSet object
        XmlDataDocument datadoc = new XmlDataDocument();

         //Open a FileStream to the Database
    	//"FileShare.ReadWrite" enables other user to also read
	//and write to the file
    	FileStream fin ;
    	fin = new FileStream(Server.MapPath(datafile), FileMode.Open,
		FileAccess.Read, FileShare.ReadWrite) ;
    	//Infer the DataSet schema from the XML data and load the XML Data
    	datadoc.DataSet.ReadXml(new StreamReader(fin));
    	//Close the stream
    	fin.Close();

	//get the total no of viewers by getting the count of the
	//no of rows present in the Table 
	showtotal.Text ="Total Viewers :"
		+datadoc.DataSet.Tables[1].Rows.Count.ToString() ;

	//databind the Repeater to the Dataset of table '1' ie the 'Viewer'
	MyDataList.DataSource = datadoc.DataSet.Tables[1].DefaultView;
       	MyDataList.DataBind();
	//free the resources
	datadoc=null ;
      }
     catch (Exception ed)
     {
       	//if there is any exception then display it 
	Response.Write("<font color=#FF0000>An Exception occured "
		+ed.ToString()+"</font>") ;
     }
  }
 </script>
</head>
<body >
<h4>Welcome to Saurabh's XML Counter Viewing Page.</h4>
 <asp:label id="showtotal" text="" runat="server" />
 <br>

  <ASP:Repeater id="MyDataList" runat="server">
     <template name="headertemplate">
	<h5> Viewer Details </h5>
     </template>
     <template name="itemtemplate">
	<br>
	<table class="mainheads" width="60%" style="font: 8pt verdana" >
        <tr style="background-color:#FFFFCC">
	  <td>Referrer :</td>
          <td>
            <%# DataBinder.Eval(Container.DataItem, "Referrer") %>
          </td></tr>
	<tr style="background-color:#FFFFCC">
	  <td>User Agent :</td>
          <td>
            <%# DataBinder.Eval(Container.DataItem, "UserAgent") %>
          </td></tr>
	<tr style="background-color:#FFFFCC">
	  <td>User Host Address :</td>
          <td>
            <%# DataBinder.Eval(Container.DataItem, "UserHostAddress") %>
          </td></tr>
	<tr style="background-color:#FFFFCC">
	  <td>User Host Name :</td>
          <td>
            <%# DataBinder.Eval(Container.DataItem, "UserHostName") %>
          </td></tr>
	<tr style="background-color:#FFFFCC">
	  <td>Browser Type :</td>
          <td>
            <%# DataBinder.Eval(Container.DataItem, "BrowserType") %>
          </td></tr>
	<tr style="background-color:#FFFFCC">
	  <td>Browser Name :</td>
          <td>
            <%# DataBinder.Eval(Container.DataItem, "BrowserName") %>
          </td></tr>
	<tr style="background-color:#FFFFCC">
	  <td>Major Version :</td>
          <td>
            <%# DataBinder.Eval(Container.DataItem, "MajorVersion") %>
          </td></tr>
	<tr style="background-color:#FFFFCC">
	  <td>Minor Version :</td>
          <td>
            <%# DataBinder.Eval(Container.DataItem, "MinorVersion") %>
          </td></tr>
	<tr style="background-color:#FFFFCC">
	  <td>Platform :</td>
          <td>
            <%# DataBinder.Eval(Container.DataItem, "Platform") %>
          </td></tr>
	<tr style="background-color:#FFFFCC">
	  <td>Date :</td>
          <td>
            <%# DataBinder.Eval(Container.DataItem, "Date") %>
          </td></tr>


        <tr style="background-color:#FFFFCC">
	<td>Time :</td>
	<td>
            <%# DataBinder.Eval(Container.DataItem, "Time") %>
          </td>
        </tr>
	</table><br>
 </template>
</ASP:Repeater>
</body>
</html>

Comments

Add Comment