Rather
than writing traditional Windows
desktop and client-server applications, more and more developers are
now writing web-based applications, even when their software is for
desktop use. There are many obvious advantages. For one, you do not
have to create as much of the user interface: you can let
Internet
Explorer and Netscape Navigator handle a lot of it
for you. Another, perhaps bigger advantage is that distribution of
revisions is faster, easier, and less expensive. When I worked at an
online network that predated the Web, we estimated our cost of
distribution for each upgrade at $1 million per diskette (remember
diskettes?). Web applications have virtually zero distribution cost.
The third advantage of web applications is distributed processing.
With a web-based application, it is far easier to provide server-side
processing. The Web provides standardized protocols (e.g., HTTP,
HTML, and XML) to facilitate building n
-tier
applications.
The .NET technology for building web applications (and dynamic web
sites) is ASP.NET, which provides a rich collection of types for
building web applications in its System.Web
and
System.Web.UI
namespaces. In this chapter,
I’ll focus on where ASP.NET and C# programming intersect: the
creation of Web Forms. (For coverage of ASP.NET alone, see my
upcoming book, Programming ASP.NET,
O’Reilly, 2001.)
Web Forms bring Rapid Application Development (RAD) techniques (such as those used in Windows Forms) to the development of web applications. As with Windows Forms, you drag and drop controls onto a form and write the supporting code either in-line or in code-behind pages. With Web Forms, however, the application is deployed to a web server, and users interact with the application through a standard browser.
Web Forms implement a programming model in which web pages are dynamically generated on a web server for delivery to a browser over the Internet. They are, in some ways, the successor to ASP pages, and they marry ASP technology with traditional programming.
With Web Forms, you create an HTML page with static content, and you write C# code to generate dynamic content. The C# code runs on the server, and the data produced is integrated with your static HTML to create the web page. What is sent to the browser is standard HTML.
Web Forms are designed to run on any browser, with the server rendering the correct browser-compliant HTML. You can do the programming for the logic of the Web Form in any .NET language. I will of course use C#, which is arguably the language of choice, though some ASP developers who have used VBScript might opt for VB .NET.
Just as with Windows Forms, you can create Web Forms in Notepad (or another editor of your choice) rather than in Visual Studio. Many developers will choose to do so, but Visual Studio makes the process of designing and testing Web Forms much easier.
Web Forms divide the user interface into two parts: the visual part or user interface (UI), and the logic that lies behind it. This is very similar to developing Windows Forms as shown in Chapter 14, but with Web Forms the UI page and the code are in separate files.
The UI page is stored in a file with the extension
.aspx
. The logic (code) for that page can be
stored in a separate code-behind
C# source file.
When you run the form, the code-behind class file runs and
dynamically creates the HTML sent to the client browser. This code
makes use of the rich Web Forms types found in the
System.Web
and System.Web.UI
namespaces of the .NET
Framework Class Library (FCL).
With Visual Studio, Web Forms programming couldn’t be simpler: open a form, drag some controls onto it, and write the code to handle events. Presto! You’ve written a web application.
On the other hand, even with Visual Studio writing a robust and complete web application can be a daunting task. Web Forms offer a very rich UI; the number and complexity of web controls have greatly multiplied in recent years, and user expectations about the look and feel of web applications have risen accordingly.
In addition, web applications are inherently distributed. Typically, the client will not be in the same building as the server. For most web applications, you must take network latency, bandwidth, and network server performance into account when creating the UI; a round trip from client to host might take a few seconds.
Web
Forms are event-driven. An
event is an
object that encapsulates the idea that
“something happened.” An event is generated (or
raised
) when the user presses a button or
selects from a list box or otherwise interacts with the UI. Events
can also be generated by the system starting or finishing work. For
example, you open a file for reading, and the system raises an event
when the file has been read into memory.
The method that responds to the event is called the event
handler
. Event handlers are written in C# in
the code-behind page and are associated with controls in the HTML
page through control attributes.
Event handlers are delegates (see Chapter 12). By convention, ASP.NET event handlers return void and take two parameters. The first parameter represents the object raising the event. The second, called the event argument , contains information specific to the event, if any. For most events, the event argument is of type EventArgs, which does not expose any properties. For some controls, the event argument might be of a type derived from EventArgs that can expose properties specific to that event type.
In web applications, most events are typically handled on the server and, therefore, require a round trip. ASP.NET only supports a limited set of events, such as button clicks and text changes. These are events that the user might expect to cause a significant change, as opposed to Windows events, such as mouse-over, that might happen many times during a single user-driven task.
Postback
events are those that cause the form to
be posted back to the server immediately. These include click type
events, such as the Button Click event. In contrast, many events
(typically change events) are considered
non-postback
in that the form is not posted back to
the server immediately. Instead, these events are cached by the
control until the next time that a postback event occurs. You can
force controls with non-postback events to behave in a postback
manner by setting their
AutoPostBack
property to true
.
A web application’s State is the current value of all the controls and variables for the current user in the current session. The Web is inherently a “stateless” environment. This means that every post to the server loses the state from previous posts, unless the developer takes great pains to preserve this session knowledge. ASP.NET, however, provides support for maintaining the state of a user’s session.
Whenever a page is posted to the server, it is re-created by the server from scratch before it is returned to the browser. ASP.NET provides a mechanism that automatically maintains state for server controls. Thus, if you provide a list and the user has made a selection, that selection will be preserved after the page is posted back to the server and redrawn on the client.
Every request for a page made from a web server causes a chain of events at the server. These events, from beginning to end, constitute the life cycle of the page and all its components. The life cycle begins with a request for the page, which causes the server to load it. When the request is complete, the page is unloaded. From one end of the life cycle to the other, the goal is to render appropriate HTML output back to the requesting browser. The life cycle of a page is marked by the following events, each of which you can handle yourself or leave to default handling by the ASP.NET server:
The ViewState property of the control is
populated. The ViewState
information comes from a
hidden variable on the control, used to persist the state across
round trips to the server. The input string from this hidden variable
is parsed by the page framework, and the ViewState
property is set. This can be modified via the LoadViewState( )
method. This allows ASP.NET to manage
the state of your control across page loads so that each control is
not reset to its default state each time the page is posted.
The client-side event that caused the postback is handled.
This is where the output to be sent back to the client browser is
generated. You can override it using the Render
method. CreateChildControls( )
is called, if
necessary, to create and initialize server controls in the control
tree.
3.133.134.17