Application State


Session state is great for storing data that is unique to each user session. Data from another user or a later session is not visible in the current session. However, if you have a lot of users, and you're storing session state values in memory, as opposed to using a database, you might run out of memory on the server. If, for example, you have 1,000 users, and each user stores 100KB of session data, that's 100MB of memory used.

Application-level state is where you can store information that is shared among all the web application's users. Anything stored here can be viewed and modified by any user. It can be accessed by any page within the application, so it is a great place for storing global data, but you need to understand that you can't count on the data in the application state sticking around for any definite period of time. If the website code is updated, a new instance of the website will be created, which means that the application state starts with a clean slate. The same thing happens if you restart the web server, so use it judiciously.

Application state works similarly to session state. You store data via key-value pairs. Here are the commonly used properties and methods:

Property/Method

Description

Count

The number of objects contained in the application state.

Item

Allows you to get or set values in the session.

Keys

The collection of keys in the object.

Add()

Adds a new value to the application state.

Clear()

Clears all objects from the application state.

GetKey()

Returns the name of the key at the specified index.

Lock()

Locks the application state until the Unlock() method is called – this allows you to make updates to objects in the application state while preventing others from doing so. Without this, two users might attempt to update the same object at the same time, causing integrity issues.

Unlock()

After you call Lock() and make your updates, you should call Unlock() to allow other users access to the application state.

Remove()

Removes a single object from the application.

RemoveAll()

Same as Clear() – removes all objects from the application.

RemoveAt()

Removes an application object at the specified index.

Set()

Updates an existing value based on the name of the key.

Data is stored in key-value pairs, so you would add data to the application state via the following statement:

 Application.Lock() Application.Add("GlobalData", "Testing") Application.Unlock() 

or using:

 Application.Lock() Application("GlobalData") = "Testing" Application.Unlock() 

It's important to call Lock() and Unlock() both when updating existing data, and when you're adding a new value as well. Otherwise, as pointed out in the table, two people might try to add the same key-value pair at the same time.

An application starts when the first request to a web application arrives after the web application has been started or restarted. An application ends when the Global.asax page is changed or the web server is shut down. As with session, we have two methods in Global.asax that execute when an application starts and ends:

  Sub Application_OnStart(Sender As Object, E As EventArgs)   ' Code that runs on application startup  End Sub  Sub Application_OnEnd(Sender As Object, E As EventArgs)   ' Code that runs on application shutdown  End Sub 

An example of what code might be used here is some database cleanup code. Some applications keep temporary data throughout the life of an application, so if the application restarts it's a good idea to clean this up.

Tracking Online Band Members in Application State

Let's give the fans the ability to see which band members are online. We'll do this by storing online information in the application state and displaying the information to the fans on a public page within the site.

Try It Out—Using Application State

When the band member logs on, we'll add their name and logon time to a hashtable in the application state. We do this by performing the following steps:

  1. Open the Secure/Login.aspx page you created in the previous chapter and change the LoginBtn_Click handler to the following:

      If Page.IsValid Then     If FormsAuthentication.Authenticate(Username.Text, UserPass.Text) Then  Application.Lock()  If Application("OnlineUsers") Is Nothing Then  Dim ht As New HashTable()  ht.Add(username.Text, Now())  Application("OnlineUsers") = ht  ElseIf Not CType( _  Application("OnlineUsers"), HashTable).Contains(Username.Text) Then  CType(Application( _  "OnlineUsers"), HashTable).Add(Username.Text, Now())  End If  Application.Unlock()  FormsAuthentication.RedirectFromLoginPage(UserName.Text, False)     Else       Msg.Text = "Invalid Credentials: Please try again"     End If   End If

  2. Now open the page used for logging out, Secure/Logout.aspx, and change the LogOffBtn_Click handler to the following:

    Sub LogOffBtn_Click(Sender As Object, E As EventArgs)  Application.Lock()  If Not Application("OnlineUsers") Is Nothing Then  CType(Application("OnlineUsers"), hashtable).Remove(User.Identity.Name)  End If  Application.Unlock()     FormsAuthentication.SignOut()     Status.Text = "Not authenticated." End Sub

This won't show anything yet, but is the groundwork that will allow us to see who is logged on.

How It Works

First, let's look at the modifications we have made to the login code.

We lock the application variable to ensure that two changes to the application state aren't attempted at the same time:

      Application.Lock()

If Application("OnlineUsers") hasn't been initialized, then we need to do so next:

      If Application("OnlineUsers") Is Nothing Then 

We're storing information about online band members in a hashtable. The key will be the band member's login name, and the value will be the time they logged in. Here, we're initializing the application object the first time with a new hashtable that contains the user's info:

        Dim ht As New HashTable()         ht.Add(username.Text, Now())         Application("OnlineUsers") = ht

If the application object has already been initialized, we check to see if the band member is already in the hashtable:

      ElseIf Not CType( _         Application("OnlineUsers"), HashTable).Contains(Username.Text) Then

If the band member isn't already in the application object, we add them now. If they are, we don't need to change anything:

        CType(Application( _           "OnlineUsers"), HashTable).Add(Username.Text, Now())       End If

Finally, we can unlock the application state object:

      Application.Unlock()

After we have unlocked the application state object, we change the FormsAuthentication to not be persistent:

      FormsAuthentication.RedirectFromLoginPage(UserName.Text, False)

This way, the band member has to log in each time they open the site in their browser. It helps us get more accurate information on when the band member is actually online.

Now, let's look at the logout code.

We first lock the application object before making changes:

  Application.Lock()

We check here to make sure Application("OnlineUsers") has been initialized:

  If Not Application("OnlineUsers") Is Nothing Then 

You might be asking why it wouldn't be, since the user had to log in before being able to log out, and we've initialized the variable in the login page. Well, as mentioned earlier, the application state can get wiped if the website changes or the application is restarted, so you should always verify the application state data before attempting to use it.

Next we remove the current user's key-value pair from the hashtable here:

    CType(Application("OnlineUsers"), hashtable).Remove(User.Identity.Name)

Finally, we unlock the application object again:

  End If   Application.Unlock()

Displaying Online Band Members

Now, let's display the online band members in a new page.

Try It Out—Displaying the Band Members

  1. Create a new page called ShowOnlineUsers.aspx. using the standard ASP.NET page template provided by Web Matrix.

  2. Drag a label control onto the page and name it lblOnlineUsers.

  3. Add the following Page_Load code, which will display all of the online users:

     Sub Page_Load(sender As Object, e As EventArgs)  Dim key As String  lblOnlineUsers.text = ""  If Not Application("OnlineUsers") Is Nothing Then  For Each key In Application("OnlineUsers").Keys  lblOnlineUsers.Text &= key & " - Logged in at " & _  CType(Application("OnlineUsers"), hashtable)(key) & "<br />"  Next  End If End Sub 

    That's it! To test it, you will need to open two browsers and do the following:

  4. Log on to the secure site in one browser as john.

  5. In the second browser, view the ShowOnlineUsers.aspx page, and you should see the following:

    click to expand

  6. Now, you can open a third browser window and log on as Al. Refresh the second browser showing the ShowOnlineUsers.aspx page, and you'll now see both member's information:

    click to expand

    Note that if you try to log off John, and refresh this page, you will see some strange behavior – don't worry, all will be explained in just a moment!

How It Works

In the code, we first initialize the variable key and clear the text in the label:

  Dim key As String   lblOnlineUsers.text = ""

We check to make sure Application("OnlineUsers") has been initialized:

  If Not Application("OnlineUsers") Is Nothing Then

We enumerate through the keys in the hashtable. As a reminder, the keys are the band members' login names:

    For Each key In Application("OnlineUsers").Keys

We add the band member's login name, a dash, and their login time to the label text:

      lblOnlineUsers.Text &= key & " - Logged in at " & _         CType(Application("OnlineUsers"), hashtable)(key) & "<br />"

At the end of this example, if you are running all these browser windows on the same machine, you will notice something strange happening if you try to log off John (the user who was first to log in to the application). Because your machine can only remember one user at a time, you can only log Al off! You may want to try this out for yourself using these three windows. The solution is that these files will work fine when hosted on a proper web server machine (one running IIS, for example). You are unlikely to want to log in to the site as more than one person from the same machine, and when this application is hosted on a full web server and browsed to by different users on different machines, you can then log off users one by one. This leaves you with a simple task of refreshing ShowOnlineUsers.aspx in your browser to see who's logged on. If we logged off John, in this example, we would then be left with just Al in the list:

click to expand

Of course, instead of having this as a separate page, you could add this code to the existing diary page. That way when fans view the diary, they could see if and band members were logged on:

click to expand

This would give the fans a way to get instant contact with band members.




Beginning Dynamic Websites with ASP. NET Web Matrix
Beginning Dynamic Websites: with ASP.NET Web Matrix (Programmer to Programmer)
ISBN: 0764543741
EAN: 2147483647
Year: 2003
Pages: 141

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