XML Counter 2
Add Comment<div align="center"> <table border="0" width="90%" class="outline"> <tr> <td width="50%" class="outline"><b>Download File</b></td> <td width="50%" class="outline"><b>SDK</b></td> </tr> <tr> <td width="50%" class="outline"><a href="file/counter2.zip" class="wbox">counter2.zip</a> (7kb)</td> <td width="50%" class="outline">Beta1</td> </tr> </table> </div> <p> <span class=wboxheado>Introduction</span><br> 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.<br> 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#. <br> <br> <span class=wboxheado>Explanation</span><br> This example consists of 2 pages.<br> 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.<br> 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.<br> 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. </p> <p align="justify"><span class=wboxheado>Requirements</span><br> 1) .NET SDK beta1 (Note: This example might not run on future versions of the SDK).<br> 2) ASP.NET hosting with appropriate permissions.</p> <p align="justify"><b>Xml Database Format</b></p> <table border="0" width="100%" class="code" cellspacing="0" cellpadding="0"> <tr> <td width="100%"><?xml version="1.0" ?> <br> <Visitors><br> <total tot="172" /> <br> <Viewer><br> <Referrer>learncsharp.cjb.net</Referrer> <br> <UserAgent>Mozilla/4.0 </UserAgent> <br> <UserHostAddress>205.184.137.153</UserHostAddress> <br> <UserHostName>205.184.137.153</UserHostName> <br> <BrowserType>IE5</BrowserType> <br> <BrowserName>IE</BrowserName> <br> <MajorVersion>5</MajorVersion> <br> <MinorVersion>0.5</MinorVersion> <br> <Platform>Unknown</Platform> <br> <Date>01/10/2001</Date> <br> <Time>09:27</Time> <br> </Viewer><br> </Visitors></td> </tr> </table> <p align="justify"><span class=wboxheado>Code</span><br> 1) <i><b>counter.aspx</b> :- The Counter Page </i></p> <table border="0" width="100%" class="code" cellspacing="0" cellpadding="0"> <tr> <td width="100%"> <pre><%@ Import Namespace="System.IO" %> <%@ Assembly Name="System.Xml" %> <%@ Import Namespace="System.Xml" %> <%@ page language="c#" EnableSessionState="True" %> <span class=cmt><%-- These are the imported assemblies and namespaces need to run the counter --%></span> <html> <head> <title>Saurabh's XML Counter Script</title> <script language="C#" runat="server"> <span class=cmt>//script is called when the page is loaded</span> public void Page_Load(Object src, EventArgs e) { <span class=cmt>//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.</span> string datafile="db/xmlcounter.xml" ; if(!Page.IsPostBack){ <span class=cmt>//try-catch block containing the counter code</span> try { <span class=cmt>//create an instance of the class XmlDocument</span> XmlDocument xmldocument = new XmlDocument() ; <span class=cmt>//Open a FileStream to the specified file </span> FileStream fin ; <span class=cmt>//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 !!!</span> fin = new FileStream(Server.MapPath(datafile), FileMode.Open, FileAccess.Read, FileShare.ReadWrite) ; <span class=cmt>//Load the Document</span> xmldocument.Load(new StreamReader(fin)) ; fin.Close(); <span class=cmt>//create an instance of the DocumentNavigator class used to //navigate through and XML file </span> DocumentNavigator navigator = new DocumentNavigator(xmldocument) ; <span class=cmt>//Move to the first element (in my file 'Visitors')</span> navigator.MoveToDocumentElement() ; <span class=cmt>//move to it child at position '0' (ie.in my file 'total' node)</span> navigator.MoveToChild(0) ; <span class=cmt>//check if we are on the right element which has an attribute</span> if (navigator.HasAttributes) { <span class=cmt>//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</span> int total = int.Parse(navigator.GetAttribute("tot")) ; <span class=cmt>//increase the counter</span> total++ ; <span class=cmt>//show the counter on the page</span> countmess.Text = "You are visitor No: "+total.ToString() ; <span class=cmt>//save the incremented counter back in the XML file</span> navigator.SetAttribute(0,total.ToString() ); } <span class=cmt>//Update the Database only if a new session is there </span> if(Session["counter"]==null) { <span class=cmt>//move back to the Document element</span> navigator.MoveToDocumentElement() ; navigator.MoveToChild(0) ; <span class=cmt>//then insert the element after the 'total' element which will //contain all the information of a single visitor </span> navigator.Insert(TreePosition.After , XmlNodeType.Element, "Viewer","",""); <span class=cmt>//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</span> 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" ; } <span class=cmt>//release the resource for Garbage collection </span> objUrl=null ; <span class=cmt>//move to parent node and then insert the information //about the useragent</span> 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 ; <span class=cmt>//to get more information of the users browsers capabilities //make an object of the HttpBrowserCapabilities class</span> 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 ; <span class=cmt>//Make an object of the DateTime class to get the Date Time </span> 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() ; <span class=cmt>//Create a File Stream again to Write to the Database //Again remember to specify the "FileShare.ReadWrite"</span> FileStream fout ; fout = new FileStream(Server.MapPath(datafile), FileMode.Open, FileAccess.Write,FileShare.ReadWrite) ; <span class=cmt>//finally save the user data to the xml database file</span> xmldocument.Save(new StreamWriter(fout)) ; <span class=cmt>//free the resources explicitly for other classes to use</span> fout.Close(); navigator=null ; xmldocument=null ; <span class=cmt>//Just store any value to the session </span> Session["counter"]=1 ; } } catch(Exception edd) { <span class=cmt>//catch other exceptions</span> 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></pre> </td> </tr> </table><P> </P> <P>2)<I> <b> viewcounter.aspx</b> : The counter information viewing page</I></P> <table border="0" width="100%" class="code" cellspacing="0" cellpadding="0"> <tr> <td width="100%"> <pre><%@ 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> <span class=cmt>//this script is execute when the page is loaded</span> public void Page_Load(Object sender, EventArgs e) { <span class=cmt>//the path to the Xml file which will contain all the data //modify this if you have any other file or directory mappings.</span> string datafile="db/xmlcounter.xml" ; <span class=cmt> </span>try { <span class=cmt>//Make an instance of the XmlDataDocument class which reads //data from a xml file and stores it in an DataSet object</span> XmlDataDocument datadoc = new XmlDataDocument(); <span class=cmt>//Open a FileStream to the Database //"FileShare.ReadWrite" enables other user to also read //and write to the file</span> FileStream fin ; fin = new FileStream(Server.MapPath(datafile), FileMode.Open, FileAccess.Read, FileShare.ReadWrite) ; <span class=cmt>//Infer the DataSet schema from the XML data and load the XML Data</span> datadoc.DataSet.ReadXml(new StreamReader(fin)); <span class=cmt>//Close the stream</span> fin.Close(); <span class=cmt>//get the total no of viewers by getting the count of the //no of rows present in the Table </span> showtotal.Text ="Total Viewers :" +datadoc.DataSet.Tables[1].Rows.Count.ToString() ; <span class=cmt>//databind the Repeater to the Dataset of table '1' ie the 'Viewer'</span> MyDataList.DataSource = datadoc.DataSet.Tables[1].DefaultView; MyDataList.DataBind(); <span class=cmt>//free the resources</span> datadoc=null ; } catch (Exception ed) { <span class=cmt> //if there is any exception then display it </span> 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></pre> </td> </tr> </table>