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

