Creating the Counter Logic


As mentioned, we ll use a cookie to track whether users have already visited our page. We need to keep track of the counter itself as well. To do this, all we need is a central repository in which we can store the current count. A good place to keep track of the count is in a text file.

In Chapter 7, we read a text file that contained a list of quotations. Here we ll need to both read and write the text file. We ll read the file to get the current counter. After updating the counter, we ll write it back out to the same text file. The text file couldn t be simpler it consists of a single line with a single number in it so it will be easier to work with than the quotations text file from Chapter 7.

To create the counter logic, we ll complete the following steps:

  1. Read the current counter from the text file. If there is no text file, we ll initialize the counter to some default value. The value 100 seems to be popular as a starting point, similar to the starting check number when you open a new checking account at the bank.

  2. Try to read the hit-counter cookie. If the cookie exists, the current user has already updated the counter. In this case, we can bail out of the counter logic because we know that the user has been counted.

  3. If we determine that the current user has not already updated the counter, we increment the counter and write it out to the text file.

  4. Set the cookie to indicate that the current user has already been counted this session.

  5. Display the counter!

Note 

The application will need permission to write a text file to the folder that contains the page. If you re deploying your application to a hosting site, you ll need to check that permission. There s a difference between you, the developer, having permission to copy files to the hosting site and the application itself being able to create and update a file at run time. If in doubt, or if you run into deploying errors, contact the hosting site administrator. For information on permissions in your Web applications, see the section Securing Your Web Applications in Appendix A.

All of this action happens right when the page is first displayed that is, in the Page_Load event handler. To create the Page_Load event handler, in the  HitCounter.aspx file, create a skeleton handler for the Page_Load event. Switch to Code view, and type in the following code:

Sub Page_Load( End Sub
Note 

I mentioned in Chapter 4 that event handlers always have two parameters. The one exception is the Page_Load handler. If you create the Page_Load event handler using the Properties window, as I described in Chapter 7, Web Matrix creates a Page_Load handler with the usual two parameters: sender and e. However, the parameters aren t required, and because we won t ever use the parameters in a Page_Load handler, the examples I show of the handler in this chapter won t include the two parameters. Note that all other event handlers, such as Click handlers for buttons, do require both parameters.

Getting the Current Counter

As mentioned, you need to read the text file to retrieve the current counter. Keep the counter in a file named HitCounter.txt., in the same folder as the  HitCounter.aspx file. You can keep the counter in any file, but if the counter text file name matches the page file name (except for extensions, naturally), there s less chance of collision if you decide to create a counter for another page.

You ll read the counter text file almost exactly the same way as you read the text file in Chapter 7 obtaining the current path and then using a StreamReader object. There s one difference, however: here you re using only one line, so you don t need a loop to get multiple lines out of the file.

The following boldfaced code shows how to read a single value out of the HitCounter.txt file and, if the file doesn t exist, initialize a counter value to 100. Note that the handler is not yet finished.

Sub Page_Load(      Dim currentCount As Integer     currentCount = 100     Dim path As String     If Not IsPostBack Then         path = Server.MapPath(Request.ApplicationPath) &  _             "\HitCounter.txt"         Try             Dim srHitCounter As New System.IO.StreamRead er(path)             currentCount = srHitCounter.ReadLine()             srHitCounter.Close()         Catch         End Try     End If End Sub

All the code for this example is inside the Page_Load handler, as noted earlier. Most of the code is also inside an If-Then block that tests the page s IsPostBack property. We don t need to perform any counting if the page is being redisplayed on postback.

We re going to keep the counter in the variable currentCount, which we declare as an integer here. We also initialize the currentCount value to 100; if we can t retrieve the current hit-counter value from the text file, we ll assume we re starting at the beginning. The variable is declared inside the Page_Load event handler and is therefore scoped to only this handler in other words, you couldn t read or write the value of this variable outside the Page_Load event handler. In this page, we ll have only this one subroutine, so we don t need to worry about declaring (hence scoping) the variable outside the handler.

Notice how we use the Try-Catch block in this example. In the Try block, we attempt to read the counter text file, and if that succeeds, we read the single line and close the file. (Remember to close anything you explicitly open.) But if the file doesn t exist in the specified path, the Try block fails and any statements in the Catch block are executed. One of the reasons that I want you to notice this block is to emphasize that when you use Try-Catch blocks, the Catch block doesn t necessarily always indicate a drastic error. You must include a Catch block or your program will stop. You decide whether the error affects your application, however. In the hit- counter example, if we can t read the hit-counter file, it s an error, but the error probably doesn t affect our application, so we don t need to stop the page and we don t even need to display an error message. In this example, therefore, the Catch block does nothing, which leaves the currentCount value at its initialized value of 100.

Checking the Cookie and Incrementing the Counter

Now that you ve read the counter from the text file, you need to determine whether you want to increment the counter and save it to the text file before you display it. Remember, you re going to use a cookie as a flag to determine whether the user has already been counted. You ll perform these tasks to check the cookie and increment the counter:

  1. Check to see whether the user already has a cookie. If no cookie is found, the current user hasn t been counted yet. If the cookie is found, the user has already been counted and we re done with counting in this page.

  2. If the user hasn t been counted, increment the counter and write it back to the counter text file.

  3. If the user doesn t have a cookie, create one for him or her so that the user will not be counted again.

The code to check the cookie and increment the counter is shown here. This code is still part of the same Page_Load handler that you were working on in the previous section; the new lines are shown in boldface.

Sub Page_Load(      Dim currentCount As Intege     currentCount = 10     Dim path As Strin     If Not IsPostBack The         path = Server.MapPath(Request.Applicat ionPath) &              "\HitCounter.txt         Try             Dim srHitCounter As New System.IO. StreamReader(path             currentCount = srHitCounter.ReadLi ne(             srHitCounter.Close(         Catc         End Tr        If Request.Cookies("HitCounter_Cookies") Is N othing Then             currentCount += 1             Try                 Dim swHitCounter As New _                     System.IO.StreamWriter(path, False)                 swHitCounter.Write(currentCount)                 swHitCounter.Flush()                 swHitCounter.Close()             Catch                 labelHitCounter.Visible = false             End Try             Response.Cookies("HitCounter_Cookies")("Alre adyCounted") = _                 True             Response.Cookies("HitCounter_Cookies").Expire s = _                 Now.AddMonths(1)        End If     End I End Sub

We ll test for the existence of a cookie by once again using the Is Nothing test. The code looks for a cookie named HitCounter_Cookies. As usual, it doesn t matter exactly what you name the cookie, as long as you read and write cookies using the same name.

If the cookie doesn t exist, you increment the variable currentCount. You then write the counter out to the text file. Writing the counter out to the text file is similar to reading it in from the text file, except that you use a StreamWriter object instead of a StreamReader object. When you create the stream writer, you pass it two parameters: the path and name of the file to write, and a Boolean flag. True means that you re going to append the counter to the file. False (our choice) means that the existing contents will be overwritten. In either case, if the file doesn t exist, it will be created automatically.

The Write method of the stream writer writes the entire file out at once. You wouldn t always program in this way. In other applications, you might write out a series of individual lines, much as you read a series of individual lines in Chapter 7.

When you ve finished writing a file, you must perform two additional tasks. The first is to flush the file, making sure that any file data still in memory is written to disk. The second is to close the file, which tells Microsoft Windows that you ve finished so that it can update file information such as the size and date of the file on disk. If you don t perform these tasks, you ll see the name of the file in the folder, but the file won t have your contents in it.

The code to write the file is also in a Try-Catch block. The stream writer will create the file if it doesn t exist, but as noted before, it s always a good idea to anticipate problems when working with resources outside the page. For example, perhaps the application doesn t have permission to create a new file. In that case, you could display an error, although users probably don t care much about problems you might be having with the hit counter. Therefore, if there s a problem with the counter text file, the Catch block simply hides the Label control by setting its Visible property to False.

Finally, we write out a cookie. In this example, we ll set an expiration date of one month from now. As mentioned earlier in this chapter, in the section Tracking Unique Hits, setting an expiration date means that the cookie will be written to the user s computer. Our example counter counts unique visitors, with the proviso that after a month, each user is counted again as a unique visitor. If you wanted to create a session cookie, you could leave out the following line, either by deleting the line or by putting an apostrophe in front of it to comment it out:

Response.Cookies("HitCounter_Cookies").Expires  = Now.AddMonths(1)

When we test for the cookie, we don t test for a specific value in the cookie; we just test to see whether the cookie exists. Nonetheless, when we re writing the cookie, we do create an entry (AlreadyCounted). You must do this so that the cookie has something to write out. Conclusion: it doesn t matter in this case what the contents of the cookie are, just that it contains something in addition to an expiration date.

Displaying the Counter

One task remains: displaying the counter. Add the single boldfaced line shown in the following code:

Sub Page_Load(      If Not IsPostBack The                  Response.Cookies("HitCounter_Cookies") .Expires =              Now.AddMonths(1     End I     labelHitCounter.Text = currentCount End Sub 

Before we display the counter, however, I want to show you a technique that you might want to use to make the number display more counter-like. (This technique is absolutely optional, by the way.) If you use the counter as is, it will display 100, 101, 102, 103, and so on. However, I wanted my counter display to be zero-padded on the front (for example, showing 00103 instead of 103). Adding the leading zeros makes it look more like an odometer-style counter.

To pad the number, I explicitly convert the counter, which is an integer, to a string by calling the ToString method. When you call the ToString method, you can optionally specify a format expression, which is a pattern or mask that will be used to display the string. To display a number with at least five characters in decimal format, you use the format expression D5. If the number is less than five characters, it will be padded with leading zeros. The line to display the counter might then look like this:

labelHitCounter.Text = currentCount.ToString(" D5")

Because I also think the number looks a little cramped, I add hard spaces around it, like this:

labelHitCounter.Text = " " & currentCount .ToString("D5") & " "
Note 

Any time you display a number, you have to convert it to a string. Microsoft Visual Basic .NET can perform the conversion automatically, which is referred to as implicit conversion. You ve displayed numbers before, such as the slide numbers in Chapter 5, and in those cases, we ve just allowed Visual Basic .NET to perform the number- to-string conversion. If you want not only to convert the number to a string but also to perform additional formatting, you need to perform an explicit conversion with the ToString method.

You can use formatting expressions to format numbers as well as dates, currency, times, and all sorts of other data types. Unfortunately, the syntax of the formatting expressions isn t very intuitive you probably wouldn t have guessed that D5 means display a number with at least five characters in decimal format so until you memorize the formatting expressions you need most often, using a formatting expression means looking it up, either in the documentation or elsewhere. You can find an overview of the Microsoft .NET Framework formatting in the article Format Specifiers and Format Providers on the Microsoft MSDN site at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/.




Microsoft ASP. NET Web Matrix Starter Kit
Microsoft ASP.NET Web Matrix Starter Kit (Bpg-Other)
ISBN: 0735618569
EAN: 2147483647
Year: 2003
Pages: 169
Authors: Mike Pope
BUY ON AMAZON

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net