|I l @ ve RuBoard|
ASP.NET handles its remote clients much the same way the family PC handles multiple local clients . By authenticating a user upon login, ASP.NET controls the scope of a client's session based on predetermined security privileges and personal settings. As soon as you start comparing how each system manages client and application communication, the similarities abruptly end. The family PC has complete control to create the most efficient environment for the client and the application. The Web server has virtually no control over the client and depends on the unreliability of the Internet. The family PC has the support of a robust message management communication protocol with all the bells and whistles. The Web server has a communication protocol just slightly more complex than the telegraph.
It's called HTTP (Hypertext Transfer Protocol) and the beauty is in its simplicity. A client makes an HTTP request by typing the URL of an HTML page she wants to view. The server processes the client's request and responds with an HTTP payload that contains the HTML data she asked for. HTTP Request + HTTP Response = Web Communication.
The clients and your server layer their HTTP request/response communications over another protocol I'm sure you've heard about: TCP/IP. TCP is the vehicle that transports HTTP payloads between the server and the clients. Just like a train, it has to separate its payloads into individual cars to hold its cargo. These cars are more commonly referred to as packets. An HTTP payload can contain HTML, XML, JPEGs, or MP3s; calls to remote programs; or just about anything else that can be converted to zeros and ones.
Your ability to extend the boundaries of the stateless HTTP protocol depends on your understanding of how ASP uses global variables at the application and client session levels. The events and variables that allow our applications to create a pseudo session state are stored in the global.asax file. As we discuss the internal structure of this file, you'll learn how we use the scope of certain variables and events to create a personalized environment that "remembers" each client between its HTTP requests . The global.asax file can be found within IIS's virtual root or within a directory that has been designated as an ASP application.
global.asax ”A Good Place to Start and End
The scope of a variable or event in a software application refers to its place in your application's object hierarchy. The top of the object hierarchy for an ASP.NET application is the Application object. The top of the object hierarchy in terms of how you manage each client that interacts with the application is the Session Object. When you create variables at these levels (global) they are accessible to every object that was created after them. The events for these objects reside in the global.asax file, which you can see in Figure 10.1.
Figure 10.1. The global.asax in VS.NET project.
Events happen. An alarm signals when it's time for you to wake up and go to work. The ringer on your telephone notifies you when someone is calling. The flip of a light switch illuminates a room. Each of these appliances help you manage and prioritize events that should make your life a little more efficient.
In object-oriented programming, you also use events to make your applications more efficient. In ASP.NET the events that have the power to start and stop your applications can be manipulated within your global.asax file.
ASP.NET adds new events to the global event file (formerly called global.asa in ASP), but the structure is extremely similar. First, let's talk about the events that have been part of ASP for a while and are still very much part of ASP.NET.
The first person that hits your Web application will inadvertently prompt ASP to fire the Application_OnStart event contained in the global.asax file. This event will not fire again. This event is where you should initialize global variables that you need to share across every user session. For example, what if you wanted to display the number of people that are currently connected to your application? Ironically, our sample application has just such a feature. When the application first starts, we declare a variable within the scope of the Application object.
Sub Application_OnStart() Application("UsersOnline") = 0 End Sub
All you have to do now is increment or decrement the value of this variable every time we start or end a client session. We'll use the Session object's Start and End events to house that portion of the code.
Sub Session_OnStart() Application("UsersOnline") = Application("UsersOnline") + 1 End Sub Sub Session_OnEnd() Application("UsersOnline") = Application("UsersOnline") - 1 End Sub
Ultimately, the performance of your application is limited by its available resources, and the variables you create at this level will require dedicated resources the entire time your application is running. Just remember that the only way to free up the resources a variable is using is to destroy the object that created it. In other words, if you created a variable within Application object's scope and you need to clear it out of memory, a simple call to the Application_OnEnd event will do the trick.
HTTP is a stateless protocol, which means that it does not have a built-in mechanism for maintaining information about each client in between each new page they request. HTTP only cares about delivering the right response for each requested page. HTTP is kind of like a fast food employee who is responsible for the quick preparation and delivery of sandwiches for every customer's order. It is so busy making sure that the customers get exactly what they requested , it doesn't have time to focus on who ordered what, and which sandwiches are for repeat customers.
The session event gives HTTP a little help with its impersonal approach to customer service. Each time a new user accesses your application, the Session_OnStart event is fired and ASP automatically assigns the visitor a unique 32-bit Session ID. ASP sends this ID in the form of a cookie that resides on the client's machine for the duration of his or her interaction with your application. Every page request that follows that initial cookie transaction will include that ID in the HTTP headers. Variables that you use within this event's scope ”including the Session ID ”are created when a client enters and are destroyed when the client's session ends.
ASP.NET will store and manage the variables associated with each customer session, but without that session ID included in each request's HTTP headers, it has no way of associating clients with their variable data. If ASP doesn't see the ID in the headers, it will assume it's a new client and issue a new ID.
Now that you have a technical sense of how ASP.NET uses the Session event to maintain a kind of pseudo-state for clients over HTTP, let's talk about a real world ASP implementation. Since ASP uses a pseudo-state, it's only appropriate for us to use a pseudo "real-world" application ”like the one included with this chapter. Let's take a look at where and when we store the variables that are unique to a client's session.
When you make your first request for a specific page, our application issues a session ID cookie and allocates some of its memory to make room for the variables we want to store. We'll use the Session object to create two variables: YourName and YourWallet . We can add, edit, or delete this information any time during the client's session.
Sub Session_OnStart() Session("YourName") = "" Session("YourWallet") = ""
We'll use the YourName variable to provide a personal touch for our visitors during their session. As a user attempts to log in to our application, we will extract their name from a textbox control and write it to this session variable. We'll add and extract the data using code like:
Session("YourName") = "GlennC" lblClientName.Text = Session("YourName") ' Extracted into a label's text property
If they have been authorized to view the Chapter10Text.aspx page, we have secret buttons hidden throughout the text that will demonstrate incremental changes to the YourWallet variable. A click on the button will perform a routine similar to the one we use for storing a count of connected users within the Application Object.
Application("UsersOnline") = Application("UsersOnline") + 1
The first page of our application prompts you for some authentication information before it allows access to any additional data. One possible option ”and the one I selected to show ”stores usernames and passwords in a file called web.config which we will talk about later. In the meantime, just remember that it is an XML-based file that we use to store our application's critical configuration information.
Like the Session_OnStart event, Session_OnEnd is fired only once per client visit. The server, the client, or the application developer can trigger this event, which will permanently destroy all of a client's session data. You can set an IIS server to automatically terminate a session if there has been no activity from that client for longer than the set time. The client can exit the application at any time, and our Session_OnEnd event will end the session accordingly . The ASP programmer can also terminate a session by making a call to this event from within his application. Here's the code we saw earlier that subtracts a user from the total count of current users.
Application("UsersOnline") = Application("UsersOnline") - 1
An Application_OnEnd event is also only fired once and will clean up its global application variables. It is only triggered by restarting the application or if the application times out after a set period of inactivity.
New .NET Application Events and "dot" Directives
The new events that Microsoft has added to the global.asax file provide us with improved control over each HTTP request and response. There are six new events that are fired for every incoming HTTP Request before we pass the request to the .NET Web service. We can authenticate client requests, we can obtain session state information, and we can even avoid the complete roundtrip altogether if we have a response that has already been processed and cached. If your Web service or ASP page encounters an error while processing the request, and you don't have code to handle the error, the Application_Error event is your last chance to handle or log any elusive errors. If they are not handled, your HTTP response will include a pretty HTML page, which contains an ugly application error message.
After the Web service or aspx page has prepared an HTTP response for the client, there are four events that are fired just before a response is delivered to the client. These events are really beyond the scope of this book and would probably only deserve an honorable mention in an intermediate book.
As you've seen in previous examples, many of the objects that you will want within your application are not readily accessible. You have to import a pointer to those objects. We call these pointers directives because they point (or direct) the system to the correct location of the objects that contain the functionality we want to use.
Assemblies are compiled applications. By default they end up as .dll or .exe files in the \bin directory underneath your application's root. An assembly is made up of your application's source code compiled into Microsoft's Intermediate Language (MSIL, or more simply IL), an XML-based text that describes your application's code and contents, and may also include binary files and additional assemblies that your application needs. Your application is Just-In-Time (JIT) compiled a second time into native machine code on the ASP.NET server.
|I l @ ve RuBoard|