Browser Applications: System.Web.UI

< BACK  NEXT >
[oR]

The idea of Web scripting embedding executable code within a Web page's HTML has been very successful. The original Active Server Pages technology was certainly one reason for this. Easy to learn and use, ASP was also widely available because it was included with the server versions of Windows NT and Windows 2000. Many thousands of ASP applications are in use today, so what this technology offers is clearly attractive. When Microsoft created ASP.NET, its successor, they faced an interesting problem: How could this new version exploit the simplicity and the installed base of ASP while still taking advantage of the consistency and power provided by the .NET Framework?

Active Server Pages has been a successful technology

The solution chosen by the designers of ASP.NET was to create an environment that can look very much like traditional ASP pages. To build browser applications, a developer can create Web pages that mix HTML and executable code just like traditional ASP pages. A relatively na ve ASP developer, one who just wrote simple scripts, could likely begin doing the same thing in ASP.NET with at most a few hours of retraining. Yet thinking about ASP.NET in this simple-minded way isn't the best approach for understanding this new technology. Instead, more advanced developers must understand that every ASP.NET application, no matter how it's constructed, is really a CLR-based application running on the .NET Framework.

ASP.NET applications are .NET Framework applications

Unlike traditional ASP technology, in which a scripting engine executes code contained in ASP pages and possibly accesses compiled COM objects, ASP.NET applications are just ordinary .NET Framework applications. Every line in a pure ASP.NET application is ultimately managed code. Yet to make them look familiar to ASP developers and to make them easy to create, Microsoft chose to allow ASP.NET browser applications to be built using pages, just like before.

As Figure 7-1 shows, an ASP.NET page that is accessed directly from a browser is stored in a text file with an extension of .aspx. When this page is accessed, it is transformed into one or more managed objects. As the figure shows, those objects can use Web controls (described later in this chapter), rely on ADO.NET to access data, and perhaps can use other services.

Figure 7-1. Each .aspx page becomes one or more managed objects when it is accessed.
graphics/07fig01.gif

Browser applications rely on .aspx pages

Managed objects always belong to some assembly, however, so each .aspx page is compiled into its own assembly. To understand how ASP.NET supports browser applications, it's useful to know a little bit about how this translation occurs.

How Browser Applications Work

An .aspx page can contain text, HTML, and executable code. Any code in the file must either be in a script block, bracketed by the tags <script> and </script>, or be wrapped in the symbols <% and %> . Here's a very simple example of an .aspx page that contains text, HTML, and a few lines of VB.NET code:

 <html> <script runat="server" language="vb"> Sub ShowNumbers()     Dim I As Integer     For I = 0 To 5        Response.Write(I)     Next End Sub </script> The date and time: <% =Now() %> <hr> Some numbers: <% ShowNumbers() %> </html> 

An .aspx page can mix text, HTML, and code

After the opening <html> tag, this page contains some very simple code inside a script block. The attributes in the opening <script> tag indicate that this code should be run at the server rather than at the client and that the code is written in Visual Basic.NET. (VB.NET is the default language for .aspx pages, so this second attribute isn't strictly required.) The code in the script block defines a method called ShowNumbers containing a simple loop that writes out the numbers 0 through 5. To accomplish this, that code calls the Write method of the Response object, a built-in ASP.NET mechanism described later in this chapter.

VB.NET is the default language for .aspx pages

After the script appear some text and, wrapped as code, a reference to Now, which returns the current date and time. The horizontal rule tag, <hr>, appears next, followed by more text and a call to the ShowNumbers method. Accessing this page from a browser produces the following:

 The date and time: 9/5/2002 5:21:05 PM ___________________________________________________________________________ Some numbers: 012345 

If you're familiar with traditional Active Server Pages, this is old hat. The script above could execute almost unchanged if it were accessed with traditional ASP technology. The only required modifications would be changing the language to vbscript and deleting the Dim statement in the ShowNumbers method. (Despite the similarities between the two technologies, most existing ASP pages will require at least small changes such as these to work with ASP.NET.)

.aspx pages look much like .asp pages

In fact, however, what's happening when this page is executed by ASP.NET is very different from what happens when a page is executed by traditional ASP. If this were an ASP page, the code it contains would be interpreted by the server, with the output it generated inserted in the stream of data sent to the browser. The text and HTML in the page would be passed through directly to the browser unchanged. If the page used COM objects, they would be written and compiled in some other language and then created and used via the standard COM mechanisms.

Traditional ASP interprets each ASP page when a request arrives

Accessing this page through ASP.NET results in a completely different execution process. ASP.NET applications are .NET Framework applications, just like those seen throughout this book. An .aspx page does look quite different from an ordinary VB.NET ***program, but that's only because the designers of ASP.NET wanted to maintain the familiar, easy-to-use model of Web scripting. The truth is that every .aspx page is automatically turned into a class and then compiled into an assembly the first time it's accessed by a client.

ASP.NET converts each .aspx page into a class that gets compiled into an assembly

Figure 7-2 gives an abstracted view of how this simple example page gets converted into a class. (What's shown here isn't literally correct the complete truth is somewhat more complicated.) The generated class's name is derived from the name of the file containing this page, and this new class must inherit from the Page class defined in System.Web.UI. As the diagram shows, any code contained in a script block is inserted into the class itself. In this case, the page's simple ShowNumbers method becomes a method in the generated class. The rest of this page, including any text, HTML tags, and code wrapped in <% %> , gets dropped into a single Render method for this class.[1]

[1] This is why code wrapped in <% ... %> can't define a method in ASP.NET. Doing this is allowed in traditional ASP, but any method defined here would become part of the body of the page class's Render method. The CLR doesn't allow one method definition to be nested inside another one, so methods in .aspx pages can be defined only inside a script block.

Figure 7-2. Each .aspx page is converted into a class, with the page's contents inserted in various places.
graphics/07fig02.gif

An .aspx page is really just another way to define a class

The class is then compiled into MSIL and packaged into an assembly. What is produced is not a static assembly, however, but rather a dynamic assembly built directly in memory using types provided by the .NET Framework class library. Once this dynamic assembly has been created, it's written to disk and then used to handle all future requests for this page. If the page is changed, the process happens again, and a new assembly is generated. In the absence of any changes, the original assembly is all that's needed, so only one compilation is required for each .aspx page.

The compiled assembly handles requests until the underlying .aspx page is changed

Understanding how a traditional ASP page generated its output was easy: The page was processed sequentially. As we've already seen, though, this isn't the case in ASP.NET. Given that each page is turned into a class before it's executed, how does that execution happen? The answer is that in place of the simple sequential processing of traditional ASP, ASP.NET uses an event-driven model. When a page is accessed, the assembly generated from that page is executed, and an instance of that assembly's page class is created. This page object receives a series of events. The object can provide a method to handle each event, and each of those methods can produce output that gets sent to the client's browser. Once all events have been handled, the page object is destroyed.

.aspx pages are executed using events

The first event every page object receives is Page_Load, sent immediately after the page object has been created. Every page object also receives a Page_Unload event just before it is destroyed. In between these two bookend events, the page object can receive and process various other events. For example, sometime prior to receiving Page_Unload, every page object will receive a Render event. This event causes the object's Render method to execute and thus displays the page's output.

Every .aspx page receives several standard events

Event-based programming will be new to many ASP developers, and understanding it will require some work. Yet a primary goal of Web scripting technologies such as ASP.NET is to create effective user interfaces. User interfaces by their nature are event driven, so it makes sense to apply this model here.

Web Controls

Event-driven user interfaces have always been the norm for Windows applications. As described in Chapter 5, for example, Windows Forms applications depend on events to get input from users. But along with events, there's another idea that's long been popular in building Windows GUIs: packaging discrete chunks of reusable functionality into controls. Each control commonly provides some part of a user interface, such as a button or text box, so they can be combined as needed to build more easily an effective GUI. Since ASP.NET has adopted the notion of event-based programming, why not introduce reusable interface components to the Web as well?

GUIs tend to have many of the same elements

This is exactly what ASP.NET's Web controls do. They're conceptually close to the Windows Forms controls described in Chapter 5, in that each one provides its own user interface and carries out its own function. Unlike Windows Forms controls, however, Web controls run on the server they're classes that become part of a page class and they produce their user interfaces by generating appropriate HTML for a browser. It's even possible for a Web control to learn what kind of browser it's communicating with and then to send the appropriate output HTML, Dynamic HTML, or something else for that browser.[2]

[2] Applications that target mobile devices such as cell phones and PDAs typically can't use standard ASP.NET Web controls effectively the screens are too small. Accordingly, Microsoft provides the Mobile Internet Toolkit for building applications that target this environment. The Toolkit includes a separate parent class for .aspx pages and a specialized set of Web controls, both specifically designed to work with small devices.

Web controls provide packaged functionality for creating a browser GUI

ASP.NET provides a large set of standard Web controls. All of them inherit from the base class WebControl in the namespace System.Web.UI.WebControls. The available choices include the common atoms of GUI design, such as Button, TextBox, CheckBox, RadioButton, and ListBox. Several more complex controls are also provided. There's a Calendar control, for instance, that displays months and allows users to select dates and an AdRotator control capable of automatically cycling through a series of Web-based advertisements. And of course, it's possible to create custom Web controls, just as there are custom Windows Forms controls. Sometimes called user controls, third parties have created a reasonably large selection of these quite quickly.

ASP.NET includes many Web controls

Here's a simple example, once again using VB.NET, that illustrates using Web controls:

 <html> <form runat="server"> <asp:Button runat="server" height="81px"      width="288px" text="Click Here"      onClick="Button_Click"/> <asp:Label  runat="server"/> </form> <script runat="server"> Sub Button_Click(Sender As System.Object, _                   e As System.EventArgs)     Label1.Text = "Button clicked" End Sub </script> </html> 

This .aspx page begins by defining a form containing two Web controls: a Button and a Label. The tag identifying both controls begins with asp: , which indicates that these controls are defined by ASP.NET. Both of these controls, along with many more, are contained in the namespace System.Web.UI.WebCon-trols. The Button element contains a number of attributes, specifying where the control should run (on the server), its height and width in pixels, and the text the Button should display. The element ends with the onClick attribute, specifying that a method called Button_Click should be run when this Button receives a Click event. The Label element also contains a few attributes. One of them, id, gives this Label a name so it can be referred to later in the page. This simple Label initially displays no text but is instead used to provide a way to send output to the browser, as described next.

Web controls can handle events

Following the form is a short script containing just the single method Button_Click. When the button is clicked, this method will be executed. The only thing this method does is assign a value to the Label's Text property, causing it to be displayed on the screen. Figure 7-3 shows the result of loading this page and clicking the button it displays. If you recall the Windows Forms example from Chapter 5, this should look familiar. Once again, a Button control is created, its size is determined, and an event handler is associated with the Button's Click event. By using Web controls, developers can build browser-based applications in a familiar style.

Figure 7-3. The simple .aspx page described in this section shows a button and then displays a message when the button is clicked.
graphics/07fig03.gif

Web controls allow building browser GUIs in a familiar style

ASP.NET's event-driven approach certainly is very similar to the event-driven model used in Windows Forms applications, and many Web controls even have the same names as their Windows Forms analogs. Still, there are significant differences between the controls used in Windows Forms applications and those used with ASP.NET applications. The most important of these grows out of the fact that while Windows applications handle events that were generated on the same machine, ASP.NET events are typically generated on the client machine and then are handled by the server system. This greatly increases the cost of raising an event, since each one results in a round trip from the browser to the ASP.NET application and back. Accordingly, there are some kinds of events that just don't make sense for Web controls.

Web controls are similar to, but not the same as, Windows Forms controls

For example, both Windows Forms and ASP.NET include a Button control. Yet the number of events supported by the Web control Button is much smaller than that supported by its Windows Forms cousin. Both Buttons support an event called Click, for instance, so an application using either one can write an event handler that runs when the control is clicked, as shown earlier. The Windows Forms control, however, also has an event called MouseMove that occurs when the mouse pointer is moved over the on-screen button, along with many other mouse-related events. None of these is available in the Web control Button. Raising each of these events on a single machine is cheap, but to send an indication to the Web server every time the mouse moves over a new control in the browser would result in an unacceptably large amount of network traffic. Accordingly, Web controls are substantially more limited in the events they can accept and process than their Windows Forms brethren.

Web controls support fewer events than Windows Forms controls

Another difference between Windows Forms controls and those used with ASP.NET is how they maintain their state. Each control has properties, such as the text it displays or its on-screen size. Windows Forms controls maintain this state in the control's memory, which is simple and efficient. Sadly, because HTTP is a stateless protocol, this isn't possible with Web controls. Like all Web-based applications, ASP.NET applications are stateless. Every object created to handle a request is destroyed when that request is completed, so an application does not by default maintain any in-memory state about a client between requests. This makes Web-based applications easy to load balance, since different requests from the same client can be sent to different machines with no problems; however, it also creates problems. One of those problems is finding a way for Web controls to maintain their state between client requests. The solution adopted by ASP.NET is to insert each control's state into the Web page sent back to the browser. When the user submits another request, the page is sent back, and this state information is copied back into each Web control. The process is arguably inelegant, but given the limitations imposed on Web-based applications, it's a good solution.

Web controls maintain state automatically between requests

One more important point remains to be made about using Web controls. Despite the simple example shown earlier, building browser GUIs by hand makes no more sense than building Windows GUIs by hand. Using a tool that allows creating a browser GUI graphically is a much better approach. Visual Studio.NET, for example, allows a developer to drag and drop Web controls on a form, set their properties, and attach code to the events they generate, just as with Windows Forms. (In fact, ASP.NET applications are sometimes referred to as Web Forms.) While it's useful to know what's going on under the covers, real applications should be built using real tools whenever possible.

Visual Studio.NET provides a graphical tool for building browser GUIs

Separating the User Interface from the Code

One problem with creating browser-based applications is the inescapable need to combine HTML and code written in a language such as VB.NET or C#. Simple pages like those shown earlier in this chapter don't create much of a problem, but real applications can get very hard to read when HTML and code are mingled on the same page. While ASP.NET allows doing this, as the examples so far have shown, it also provides a mechanism for cleanly separating the GUI-oriented HTML from the code behind that GUI. Appropriately, this mechanism is called code-behind.

Code and HTML can be separated using the code-behind option

Code-behind is a straightforward idea. Rather than mixing HTML and code in a single file, using the code-behind option allows putting all of a page's HTML in its .aspx file and then inserting a reference in that file to another file that contains the code. The result is significantly easier to work with, since the two very different worlds of HTML and a CLR-based programming language can remain distinct from one another.

Code-behind can make applications more maintainable

Here's how the simple application just shown might look if this option were used. The file containing just the code is as follows:

 Imports System Imports System.Web.UI.WebControls Public Class Example     Inherits System.Web.UI.Page     Protected Label1 As Label     Protected myButton As Button     Sub Button_Click(sender As Object,_                       e As EventArgs)         Label1.Text = "Button clicked"     End Sub End Class 

This is effectively the same code that appeared in the script block in the previous example. It begins with a couple of Imports statements to make what follows more readable; then it declares a class named Example. This class inherits from the base Page class that underlies all .aspx pages. The two controls, both of which are contained in the System.Web.UI.WebCon-trols namespace, are declared next. Both are marked as Protected, which means they can be accessed only from within this class or a child of this class. The class ends with the definition of Button_Click, the same simple method shown in the previous example.

With the code cabined off in a separate file, the .aspx file now looks like this:

 <%@Page Inherits="Example" src="/books/2/78/1/html/2/Code.vb" %> <html> <form runat="server"> <asp:Button runat="server" height="81px"          width="288px" text="Click Here"          onClick="Button_Click"/> <asp:Label  runat="server"/> </form> </html> 

The file begins with a Page directive. This line tells the ASP.NET infrastructure that the code for this page is in a class named Example in the file Code.vb. In other words, this directive connects this purely HTML file with the VB.NET code that it uses. The rest of the file is just the HTML from the example shown earlier. With the code removed, the user interface aspects of this very simple application are much clearer, as the entire page can now contain purely HTML.

Using code-behind is a good idea. Visual Studio.NET, for example, automatically creates new Web applications in this format. For anything beyond the simplest ASP.NET browser applications, it's the way to go.

Other Topics

Processing .aspx pages, using Web controls, and understanding the idea of code-behind are arguably the most important aspects of ASP.NET. There are plenty more, however, and really understanding this technology requires a grasp of ASP.NET applications, state management, and other issues. This section takes a brief look at these topics.

ASP.NET Applications

ASP.NET allows grouping .aspx pages, assemblies, and other files into an ASP.NET application. To do this, the files that comprise the application must be installed beneath a common directory. Each ASP.NET application can also have application-wide logic stored in a global.asax file. This file, analogous to the global.asa files used with traditional ASP, can contain code that runs when the application is first executed, when it ends, when a new client begins a session with the application, and at various other times. Each ASP.NET application also has its own web.config file that controls many aspects of the application's behavior.

An ASP.NET application can contain .aspx pages, assemblies, and more

Is ASP.NET Too Hard?

Microsoft's original Active Server Pages technology was a huge hit. A primary reason for this was that it was incredibly easy to use, and so everybody and his dog Rover wrote ASP applications. True, this initial ease of use tended to devolve into unmaintainable code for applications of any size, but the barriers to entry for this technology were very low.

ASP.NET provides much more than the original ASP. Accordingly, it's more complex. In fact, using ASP.NET effectively requires understanding the CLR, since all code must be written in a CLR-based language such as VB.NET or C#. Classes, events, inheritance, and a host of other more advanced concepts will descend on unsuspecting ASP developers like fog on a San Francisco evening. While writing real ASP applications required some technical knowledge using COM components well isn't simple ASP.NET asks even more of at least some of its developers.

Suppose Microsoft had shipped ASP.NET originally and that the original ASP technology had never existed. Would ASP have become so widely used? I'm inclined to doubt it. ASP.NET's barriers to entry are noticeably higher for beginners. Still, this new technology does make some accommodation for newcomers, while still providing plenty of functionality for serious developers. Like many other things in the .NET Framework (VB.NET comes immediately to mind), ASP.NET expects more from developers than did Windows DNA. Upping the technical ante will please most customers, but some are likely to be left behind.

Figure 7-4 shows the files comprising two different ASP.NET applications. The simple retirement calculator application has two .aspx files and a web.config file. The slightly more complex account management application has two .aspx files, a global.asax file and a web.config file. It also has two assemblies, each of which consists of only a single DLL. As the figure shows, assemblies that are part of an ASP.NET application are stored in a bin directory below the application's root directory.

Figure 7-4. Each ASP.NET application can include pages, assemblies, a configuration file, and more.
graphics/07fig04.gif

ASP.NET applications can be installed by just copying their files

Because ASP.NET applications are .NET Framework applications, installing an ASP.NET application requires just copying the application's files to the target machine. No registry entries are required (unless COM interoperability is used), and there's no need to restart IIS to begin using the new application. Deleting the application is equally simple all that's required is deleting the application's files. It's even possible to install new versions of pages or assemblies while an ASP.NET application is running. Requests in progress will complete using the old code, while new requests will automatically use the new version.

The ASP.NET worker process hosts all ASP.NET applications, each in its own app domain

Although it may seem odd at first, all code from all ASP.NET applications is loaded into the same Windows process. Sometimes called the ASP.NET worker process, it's implemented in aspnet_wp.exe. Requests from clients are handled first by IIS and then passed on to the appropriate ASP.NET application within this worker process. Loading a group of unrelated applications into a single process sounds dangerous. What happens if code from one application accesses the memory space of another one? This is a potential problem in the traditional ASP world, but it's not something developers need to worry about with ASP.NET. As Figure 7-5 shows, each ASP.NET application is loaded into its own application domain, so each application is completely isolated from any other. This is just another example of the myriad ways in which the traditional ASP model has been adapted to the .NET Framework.

Figure 7-5. Each ASP.NET application runs in its own application domain.
graphics/07fig05.gif
Built-in Objects

When a request from a client is processed, that request passes through a series of objects sometimes referred to collectively as the HTTP pipeline. These objects all need access to information about the request, so an instance of the HttpContext class, contained in the System.Web namespace, is created for each incoming request. This object is available throughout the HTTP pipeline, allowing the objects in the pipeline to share information about a particular request. To allow this sharing of information, the HttpContext object contains a large number of properties, including the following:

  • Request: Allows access to the HttpRequest object for this request. This object's properties contain information about the request, such as the HTTP query string that accompanied it, the client's IP address, any cookies that accompanied it, and much more.

  • Response: Allows access to the HttpResponse object for this request. This object provides a large group of methods and properties focused on sending information back to the requesting client. Perhaps the most commonly used of these is the Write method illustrated in the example pages shown earlier, which directly sends output back to the client.

  • Application: Allows access to the HttpApplicationState object for this request. This object stores information relevant for the entire ASP.NET application. Its methods include Add, which allows adding an arbitrary object to a collection maintained by this object; Get, which allows accessing an object in this collection; and Set, which allows modifying an object in this collection.

  • Cache: Allows storing information for an ASP.NET application. The Cache object is similar to the Application object, but it provides several extra features. For example, information stored in this object can be set to expire in a specific period of time or to exist only as long as a specific file exists.

  • Session: Allows access to the HttpSessionState object for this request. This object stores information solely about the client that made this request. Like HttpApplicationState, it allows adding, reading, and modifying arbitrary objects in a collection. This object is especially important, so it's described in more detail later in this chapter.

  • Error: Allows access to an Exception object for an error that occurred during processing of this request.

  • User: Contains the identity of the client that initiated this request.

  • Handler: Allows access to the instance of an HttpHandler class associated with this request. HTTP handlers allow access to the low-level functions of processing a request. Rather than writing code using the Internet Server API (ISAPI), such as an ISAPI extension, you can create a custom HTTP handler instead. As was true for ISAPI extensions, most people won't need to write their own handlers, but ASP.NET provides this relatively low-level option for hard-core .NET developers.

.aspx pages can use several different built-in objects

If you're familiar with traditional ASP, many of these objects will look familiar. In the ASP world, Request, Response, Session, Application, and Error are all COM objects available to applications. With ASP.NET, the same information (and more) is available via the HttpContext object. In fact, the most important properties of this object are also accessible directly through the Page class. The properties that Page provides include Request, Response, Session, Application, Error, and Cache, each of which is actually a way to access the corresponding property of the HttpRequest object for this request. Since Page is the parent class for every .aspx page, this information is readily accessible to every application.

Many of these objects are also available in traditional ASP

Among the most interesting of these objects are those used to manage an application's state. State management is a key issue for most ASP.NET applications, and as described next, there are several choices for how it's done.

Managing State

Every request a client makes to an ASP.NET application causes the objects on the loaded page to be created, used, and then destroyed. This helps in building scalable applications, since no resources are taken up on the server for clients that aren't currently running requests. It can also make writing those applications more difficult, however. If all of an application's objects forget everything they've been told after every request, the application won't be very intelligent. To make it easier to create smarter software, ASP.NET provides several different ways for an application to maintain state information between client requests.

Objects in an .aspx page can't maintain their state internally between requests

As already described, the properties in Web controls are automatically saved by inserting their values into the Web pages sent to the user and then reading those values out again when the page is sent back. Using a state bag, an application developer can rely on this same approach to store any other information maintained by a particular page. This inelegantly named mechanism allows an application to store any values it wishes and have them restored when the user resubmits the page. Like Web controls, the information in the state bag is saved as fields in the page sent to the user.

Information used throughout an application can be saved in the Application object

Yet the state bag saves information only for a particular page in an ASP.NET application. What if you want to save information used by several pages in the application? To do this, an application can use the Application object mentioned earlier. Rather than being sent to the client with each page, information placed in the Application object is maintained on the server and made accessible to all pages in an application. A reference to the Application object from any page in an ASP.NET application will always access the same instance. For example, if an application wishes to record the time at which some event takes place and then let that time be accessed by another page in the same application, it might contain the following line:

 <% Application("Timestamp") = Now() %> 

A page that wished to access the value of this variable can reference it directly, as in

 <% response.write (Application("Timestamp")) %> 

Information used throughout an application can be saved in the Application object

This book hasn't said much about threading in the .NET Framework, but it's important to note that ASP.NET applications are multithreaded. Since there's only one Application object for an entire ASP.NET application, if two different pages running on two different threads write to it simultaneously, problems can occur. Depending on the threading choices an application uses, explicit concurrency controls might be needed to avoid conflicts.

Alternatively, the Cache object can be used instead of the Application object. As mentioned earlier, the objects are broadly similar in function. The biggest difference is that the Cache object allows much more control over how long information is held and what causes it to be removed. An application can also ask that it be informed when a particular item is deleted from the Cache object, providing an event handler that runs when the information is deleted.

Information used throughout an application can also be stored in the Cache object

Storing state in either of these objects has a problem, however: Both are physically stored on a single machine. If an ASP.NET application is deployed on several Web servers, with client requests load balanced across those servers, storing state in the Application or Cache objects will be problematic. Each copy of the application will have its own instance of these objects, so the information these instances contain will likely be different. Applications that will be load balanced should be careful about how, or even if, they use these objects.

Load balancing complicates state management

The options just described can be useful ways for an application to store state. Yet none of them addresses the most common state management problem in building ASP.NET applications: maintaining per-client state. Think, for example, of a Web application that allows its user to add items to a shopping cart. Given that the objects created by the application are destroyed after every request, how can that information be retained? Every page accessed by that client (and only that client) within an ASP.NET application should have easy access to this per-client state, but nothing described so far provides this. Yet building reasonable applications requires some way to store client-specific information across the life of a client session. In ASP.NET, the Session object provides a way to do this.

Information used throughout a single client session can be stored in the Session object

Accessing a Session object looks much like accessing the Application object. To store a value, an .aspx page can contain a line such as

 Session("ItemSelected")= 13 

To access that value, the page can simply refer to it as in

 response.write(Session("ItemSelected")) 

Even though Session and Application objects are accessed in a similar way, don't be confused. There's only one Application object shared by all pages in an ASP.NET application, while every client has its own Session object. When an application accesses the Session object, it will always get the instance associated with the client that made this request. To figure out which client each request comes from, ASP.NET assigns each client a unique 120-bit session identifier that gets stored in a cookie. The client then presents this cookie with each request it makes, allowing ASP.NET to identify all requests that come from the same client. Users can turn off cookies if they wish, however, so ASP.NET is also capable of embedding this identifier in the URL string returned to a user. However it's done, the creator of an ASP.NET application doesn't need to worry about determining which request comes from which user it's done for him.

One Session object can exist for each active client

In traditional ASP, the Session object worked much as described here. Yet while that older version of the Session object is easy to use, it's also deadly. The ASP Session object is bound to a single machine, much like the Application object today. If an ASP application is load balanced across several different machines, only one of those machines will store this object. Requests from this client that get sent to other machines due to load balancing won't be able to access the object's contents, so they won't execute correctly. As a result, using ASP's Session object greatly limits an application's scalability.

Traditional ASP's Session object doesn't work well with load balancing

This limitation doesn't exist in ASP.NET. The Session object for a particular client can still be stored on just one machine, as in traditional ASP, but it can also be stored in a separate Session State Store. If this is done, the contents of the Session object are available to all copies of the application running on all machines in a load-balanced configuration. And because the state is in another process (and perhaps another machine), it can remain available even if the ASP.NET application itself is restarted.

ASP.NET's Session object does work well with load balancing

The Session object can store its state in several different ways

The standard Session State Store server provided with the .NET Framework provides four options:

  • InProc: The Session object is stored in the same process as the application. This is much like the Session object in traditional ASP, and it's the default setting.

  • StateServer: The Session object's state is stored in another process that can run locally or on another machine.

  • SQLServer: The Session object's state is stored on disk using SQL Server.

  • Off: The Session object is disabled.

Any state in the Session object is automatically destroyed when a client hasn't accessed the application for a configurable length of time. It's also possible to write your own session state server and plug it in to the ASP.NET infrastructure (or more correctly, insert it into the HTTP pipeline) in place of a standard solution. Note too that how the Session object's state is stored depends entirely on the contents of an application's web.config file. No code in the application needs to be modified to change which option is used.

Output caching allows saving recently accessed results in memory

Finally, although it's not state management in quite the same way as the choices just described, ASP.NET's output caching option is also worth describing here. (Don't confuse this with the Cache object described earlier, which is a separate idea.) Caching repetitively accessed data is an effective way to speed up applications. Rather than doing the work required to recreate that data each time it's requested, the information can be read quickly from an in-memory cache and returned. To use ASP.NET's caching mechanism, an .aspx page can contain a directive such as

 <%@ OutputCache Duration="60" VaryByParam="none" %> 

The duration specifies how long (in seconds) the results of that page can be cached before the information must be recreated. Requests that arrive for the same information within this period will have their responses returned immediately from the cache.

Output caching has several options

The required VaryByParam attribute is set to none in this example, but if desired, it can be used to control exactly which results are cached. The parameter this attribute refers to can be any named value contained in a query string, which is the text following a ? on a client request. For example, suppose an .aspx page contained the directive

 <%@ OutputCache Duration="60" VaryByParam="name" %> 

Suppose further that this page received two requests with these query strings:

 http://www.qwickbank.com/page1.aspx?name=Bob http://www.qwickbank.com/page1.aspx?name=Casey 

Because output caching was instructed to vary by a parameter called name, the results of each request would be cached. Requests to this page with names of either Bob or Casey that are received within the 60-second window specified on the Duration attribute will return cached results. Other things, such as the type of browser from which a request originated, can also be used to control exactly which pages are cached. The result is a more responsive application, especially if the same data is accessed over and over.

ASP.NET Security

Securing Web applications is incredibly important. Internet viruses have made even nonprofessionals aware of the dangers of too little security. Unfortunately, really understanding Web security is a large topic, one that's outside the scope of this chapter's short description. Nevertheless, it's worth making a few points about what ASP.NET provides in this area.

Browser applications must be secure

ASP.NET provides several options for authenticating users

The System.Web.Security namespace contains a large set of types that can be used to provide security services for ASP.NET applications. The primary focus is on authentication, that is, on proving you are who you say you are. Although a developer is free to create her own authentication mechanism, ASP.NET applications have several authentication options provided for them. The choices include the following:

  • Windows authentication: Based on what's built into IIS, there are three options. Basic authentication, simplest of the three, requires a client to send an unencrypted password across the network, which by itself is no one's idea of good security. Digest authentication, the second choice, requires a client to send a hashed version of a password and other information, which provides somewhat better security. The third option, called Integrated Windows Authentication, allows using the authentication protocol available in a Windows domain, such as Kerberos. This choice is quite secure, but it's generally available only on intranets and only when the client browser is Internet Explorer.

  • Forms authentication: A mechanism new with ASP.NET, this option allows an application to display a custom form to acquire user credentials, such as a login name and password and then to decide whether the user is who she claims to be. It relies on the Secure Sockets Layer (SSL) protocol to ensure that those credentials are encrypted when initially sent across the network.

  • Passport authentication: Allows using Microsoft's Internet-based Passport service. System.Web.Security contains several classes that allow applications to access Passport and then use the authenticated client identity it provides.

Once a client has been authenticated, the next step is to make an authorization decision for that client, that is, to determine what the client is allowed to do. If one of the Windows authentication options is used, a client's attempt to access a particular file such as an .aspx file will be subject to the usual access controls. This means that Windows will automatically check the access control list (ACL) on the file to ensure that the user's request is allowed. With Windows authentication or any of the other authentication options, an approach called URL authorization is also available. This option allows fine-grained control over who is allowed to perform what operations against a particular ASP.NET application.

ASP.NET applications can make an authorization decision in different ways

With .aspx pages, ASP.NET lets developers create what has become the norm today: applications that are accessed through a browser. While the name and some parts of the technology are derived from the original ASP technology, ASP.NET is a complete rewrite and a rethink of how to build browser-accessible applications on the .NET Framework. Implemented almost entirely as types in the .NET Framework class library, the services it provides will be used by many, many developers. Yet browser-accessible applications aren't the only way to use the Web today. Web services also matter, and ASP.NET allows creating this new kind of application as well. How this can be done is described next.

ASP.NET redesigns ASP from the ground up

< BACK  NEXT >


Understanding. NET. A Tutorial and Analysis
Understanding .NET: A Tutorial and Analysis (Independent Technology Guides)
ISBN: 0201741628
EAN: 2147483647
Year: 2002
Pages: 60

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