Web Forms Architecture

for RuBoard

A Web Form consists of two parts :

  • The visual content or presentation, typically specified by HTML elements

  • Code that contains the logic for interacting with the visual elements.

A Web Form is physically expressed by a file with the extension .aspx . Any HTML page could be renamed to have this extension and could be accessed using the new extension with identical results to the original. Thus Web Forms are upwardly compatible with HTML pages.

The way code can be separated from the form is what makes a Web Form special. This code can be either in a separate file (having an extension corresponding to a .NET language, such as .cs for C#) or in the .aspx file, within a <SCRIPT RUNAT ="SERVER"> ... /SCRIPT> block. When your page is run in the Web server, the user interface code runs and dynamically generates the output for the page.

We can understand the architecture of a Web Form most clearly by looking at the code-behind version of our "echo" example. The visual content is specified by the .aspx file HelloCodebehind.aspx .

 <!-- HelloCodebehind.aspx -->  <%@ Page Language="C#" Src="HelloCodebehind.aspx.cs"  Inherits= MyWebPage %>  <HTML>    <HEAD>    </HEAD>  <BODY>  <FORM RUNAT="SERVER">YOUR NAME:&nbsp;  <asp:textbox id=txtName Runat="server"></asp:textbox>  <p><asp:button id=cmdEcho onclick=cmdEcho_Click Text="Echo"  runat="server" tooltip="Click to echo your name">  </asp:button></p>     <asp:label id=lblGreeting runat="server"></asp:label>  <P></P>  </FORM>  </BODY>  </HTML> 

The user interface code is in the file HelloCodebehind.aspx.cs ,

 // HelloCodebehind.aspx.cs  using System;  using System.Web;  using System.Web.UI;  using System.Web.UI.WebControls;  public class MyWebPage : System.Web.UI.Page  {     protected TextBox txtName;     protected Button cmdEcho;     protected Label lblGreeting;     protected void cmdEcho_Click(object Source, EventArgs e)     {        lblGreeting.Text="Hello, " + txtName.Text;     }  } 

Page Class

The key namespace for Web Forms and Web Services is System.Web . Support for Web Forms is in the namespace System.Web.UI . Support for server controls such as text boxes and buttons is in the namespace System.Web.UI.WebControls . The class that dynamically generates the output for an .aspx page is the Page class, in the System.Web.UI namespace, and classes derived from Page , as illustrated in the code behind page in this last example.

Inheriting from Page Class

The elements in the .aspx file, the code in the code-behind file (or script block), and the base Page class work together to generate the page output. This cooperation is achieved by ASP.NET's dynamically creating a class for the .aspx file, which is derived from the "code-behind" class, which in turn is derived from Page . This relationship is created by the "Inherits" attribute in the .aspx file. Figure 10-6 illustrates the inheritance hierarchy. Here MyWebPage is a class we implement, derived from Page .

Figure 10-6. Hierarchy of page classes.

graphics/10fig06.gif

The most derived page class, shown as "My .aspx Page" in Figure 10-6, is dynamically created by the ASP.NET runtime. This class extends the page class, shown as "MyWebPage" in the figure, to incorporate the controls and HTML text on the Web Form. This class is compiled into an executable, which is run when the page is requested from a browser. The executable code creates the HTML that is sent to the browser.

Web Forms Page Life Cycle

We can get a good high-level understanding of the Web Forms architecture by following the life cycle of our simple Echo application. We will use the code-behind version (the second example), HelloCodebehind.aspx .

  1. User requests the HelloCodebehind.aspx Web page in the browser.

  2. Web server compiles the page class from the .aspx file and its associated code behind page. The Web server executes the code, creating HTML, which is sent to the browser. (In Internet Explorer you can see the HTML code from the menu View Source.) Note that the server controls are replaced by straight HTML. The following code is what arrives at the browser, not the original code on the server .

     <!-- HelloCodebehind.aspx -->  <HTML>    <HEAD>    </HEAD>  <BODY>  <form name="ctrl0" method="post"  action="HelloCodebehind.aspx" id="ctrl0">   <input type="hidden" name="__VIEWSTATE"  value="dDwxMzc4MDMwNTk1Ozs+" />  YOUR NAME:&nbsp; <input name="txtName" type="text"  id="txtName" />  <p><input type="submit" name="cmdEcho" value="Echo"  id="cmdEcho" title="Click to echo your name" /></p>     <span id="lblGreeting"></span>  <P></P>  </form>  </BODY>  </HTML> 
  3. The browser renders the HTML, displaying the simple form shown in Figure 10-7. To distinguish this example from the first one, we show "YOUR NAME" in all capitals. Since this is the first time the form is displayed, the text box is empty, and no greeting message is displayed.

    Figure 10-7. The form for the "Echo" application is displayed for the first time.

    graphics/10fig07.gif

  4. The user types in a name (e.g., "Mary Smith") and clicks the "Echo" button. The browser recognizes that a Submit button has been clicked. The method for the form is "post" [1] and the action is "HelloCodebehind.aspx." We thus have what is called a "post back" to the original .aspx file.

    [1] The HTTP POST method sends form results separately as part of the data body, rather than by concatenating it onto the URL, as is done in the GET method.

  5. The server now performs processing for this page. An event was raised when the user clicked the "Echo" button, and an event handler in the MyWebPage class is invoked.

     protected void cmdEcho_Click(object Source, EventArgs e)  {     lblGreeting.Text="Hello, " + txtName.Text;  } 
  6. The Text property of the TextBox server control txtName is used to read the name submitted by the user. A greeting string is composed and assigned to the Label control lblGreeting , again using property notation.

  7. The server again generates straight HTML for the server controls and sends the whole response to the browser. Here is the HTML.

     ...  <form name="ctrl0" method="post"  action="HelloCodebehind.aspx" id="ctrl0">  <input type="hidden" name="__VIEWSTATE"  value="dDwxMzc4MDMwNTk1O3Q8O2w8aTwyPjs+O2w8dDw7bDxpPDU+Oz47b  Dx0PHA8cDxsPFRleHQ7PjtsPEhlbGxvLCBNYXJ5IFNtaXRoOz4+Oz47Oz47P  j47Pj47Pg==" />  YOUR NAME:&nbsp; <input name="txtName" type="text"  value="Mary Smith"  id="txtName" />  <p><input type="submit" name="cmdEcho" value="Echo"  id="cmdEcho" title="Click to echo your name" /></p>     <span id="lblGreeting">  Hello, Mary Smith  </span>  ... 
  8. The browser renders the page, as shown in Figure 10-8. Now a greeting message is displayed.

    Figure 10-8. After a round trip a greeting message is displayed.

    graphics/10fig08.gif

View State

An important characteristic of Web Forms is that all information on forms is " remembered " by the Web server. Since HTTP is a stateless protocol, this preservation of state does not happen automatically but must be programmed. A nice feature of ASP.NET is that this state information, referred to as "view state," is preserved automatically by the Framework, using a "hidden" control.

 ...  <input type="hidden" name="__VIEWSTATE"  value="dDwxMzc4MDMwNTk1O3Q8O2w8aTwyPjs+O2w8dDw7bDxpPDU+Oz47b  Dx0PHA8cDxsPFRleHQ7PjtsPEhlbGxvLCBNYXJ5IFNtaXRoOz4+Oz47Oz47P  j47Pj47Pg==" />  ... 

Later in the chapter we will examine other facilities provided by ASP.NET for managing session state and application state.

Web Forms Event Model

From the standpoint of the programmer, the event model for Web Forms is very similar to the event model for Windows Forms. Indeed, this similarity is what makes programming with Web Forms so easy. What is actually happening in the case of Web Forms, though, is rather different. The big difference is that events get raised on the client and processed on the server. [2]

[2] Some controls, such as the Calendar control, raise some events on the server. Also, the Page itself raises events on the server.

Our simple form with one text box and one button is not rich enough to illustrate event processing very thoroughly. Let's imagine a more elaborate form with several text boxes, list boxes, check boxes, buttons, and the like. Because round trips to the server are expensive, events do not automatically cause a postback to the server. Server controls have what is known as an intrinsic event set of events that automatically cause a postback to the server. The most common such intrinsic event is a button click. Other events, such as selecting an item in a list box, do not cause an immediate postback to the server. Instead, these events are cached, until a button click causes a post to the server. Then, on the server the various change events are processed, in no particular order, and the button-click event that caused the post is processed.

Page Processing

Processing a page is a cooperative endeavor between the Web server, the ASP.NET runtime, and your own code. The Page class provides a number of events, which you can handle to hook into page processing. The Page class also has properties and methods that you can use. We cover some of the major ones here. For a complete description, consult the .NET Framework documentation. The example programs in this chapter will illustrate features of the Page class.

Page Events

A number of events are raised on the server as part of the normal processing of a page. These events are actually defined in the Control base class and so are available to server controls also. The most important ones are listed below.

  • Init is the first step in the page's life cycle and occurs when the page is initialized . There is no view-state information for any of the controls at this point.

  • Load occurs when the controls are loaded into the page. View-state information for the controls is now available.

  • PreRender occurs just before the controls are rendered to the output stream. Normally this event is not handled by a page but is important for implementing your own server controls.

  • Unload occurs when the controls are unloaded from the page. At this point it is too late to write your own data to the output stream.

Page Properties

The Page class has a number of important properties. Some of the most useful are listed below.

  • EnableViewState indicates whether the page maintains view state for itself and its controls. You can get or set this property. The default is true , view state is maintained .

  • ErrorPage specifies the error page to which the browser should be redirected in case an unhandled exception occurs.

  • IsPostBack indicates whether the page is being loaded in response to a postback from the client or is being loaded for the first time.

  • IsValid indicates whether page validation succeeded. [3]

    [3] We discuss validation later in the chapter, in the section on Server Controls.

  • Request gets the HTTP Request object, which allows you to access data from incoming HTTP requests.

  • Response gets the HTTP Response object, which allows you to send response data to a browser.

  • Session gets the current Session object, which is provided by ASP.NET for storing session state.

  • Trace gets a TraceContext object for the page, which you can use to write out trace information.

Sample Program

We can illustrate some of these features of page processing with a simple extension to our Echo program. The page HelloPage.aspx (located in the top-level chapter directory) provides handlers for a number of page events, and we write simple text to the output stream, using the Response property. For each event we show the current text in the txtName and lblGreeting server controls. In the handler for Load we also show the current value of IsPostBack , which should be false the first time the page is accessed, and subsequently true .

 <!-- HelloPage.aspx -->  <%@ Page Language="C#" Debug="true" %>  <HTML>  <HEAD>   <SCRIPT RUNAT="SERVER">  protected void cmdEcho_Click(object Source, EventArgs e)  {     lblGreeting.Text="Hello, " + txtName.Text;  }  protected void Page_Init(Object sender, EventArgs E)  {     Response.Write("Page_Init<br>");     Response.Write("txtName = " + txtName.Text + "<br>");     Response.Write("lblGreeting = " + lblGreeting.Text +                    "<br>");  }  protected void Page_Load(Object sender, EventArgs E)  {     Response.Write("Page_Load<br>");     Response.Write("IsPostBack = " + IsPostBack + "<br>");      Response.Write("txtName = " + txtName.Text + "<br>");     Response.Write("lblGreeting = " + lblGreeting.Text +                    "<br>");  }  protected void Page_PreRender(Object sender, EventArgs E)  {     Response.Write("Page_PreRender<br>");     Response.Write("txtName = " + txtName.Text + "<br>");     Response.Write("lblGreeting = " + lblGreeting.Text +                    "<br>");  }  protected void Page_Unload(Object sender, EventArgs E)  {     //Response not available in this context     //Response.Write("Page_Unload<br>");  }  </SCRIPT>  </HEAD>  <BODY>  <FORM RUNAT="SERVER">Your name:&nbsp;  <asp:textbox id=txtName Runat="server"></asp:textbox>  <p><asp:button id=cmdEcho onclick=cmdEcho_Click Text="Echo"  runat="server" tooltip="Click to echo your name">  </asp:button></p>  <asp:label id=lblGreeting runat="server"></asp:label>  <P></P>  </FORM>  </BODY>  </HTML> 

When we display the page the first time the output reflects the fact that both the text box and the label are empty, since we have entered no information. IsPostBack is false .

Now enter a name and click the "Echo" button. We obtain the following output from our handlers for the page events:

 Page_Init  txtName =  lblGreeting =  Page_Load  IsPostBack = True  txtName = Robert  lblGreeting =  Page_PreRender  txtName = Robert  lblGreeting = Hello, Robert 

In Page_Init there is no information for either control, since view state is not available at page initialization. In Page_Load the text box has data, but the label does not, since the click-event handler has not yet been invoked. IsPostBack is now true . In Page_PreRender both controls now have data.

Click "Echo" a second time. Again, the controls have no data in Page_Init . This time, however, in Page_Load the view state provides data for both controls. Figure 10-9 shows the browser output after "Echo" has been clicked a second time.

Figure 10-9. Browser output after "Echo" has been clicked a second time.

graphics/10fig09.gif

Page Directive

An .aspx file may contain a page directive defining various attributes that can control how ASP.NET processes the page. A page directive contains one or more attribute/value pairs of the form

 attribute="value" 

within the page directive syntax

 <@ Page ... @> 

Our example program HelloCodebehind.aspx illustrates an .aspx page that does not have any code within it. The "code-behind" file HelloCodebehind.aspx.cs that has the code is specified using the Src attribute.

 <!-- HelloCodebehind.aspx -->  <%@ Page Language="C#" Src="HelloCodebehind.aspx.cs"  Inherits=MyWebPage %>  ... 
Src

The Src attribute identifies the code-behind file.

Language

The Language attribute specifies the language used for the page. The code in this language may be in either a code-behind file or a SCRIPT block within the same file. Values can be any .NET-supported language, including C# and VB.NET.

Inherits

The Inherits directive specifies the page class from which the .aspx page class will inherit.

Debug

The Debug attribute indicates whether the page should be compiled with debug information. If true , debug information is enabled, and the browser can provide detailed information about compile errors. The default is false .

ErrorPage

The ErrorPage attribute specifies a target URL to which the browser will be redirected in the event that an unhandled exception occurs on the page.

Trace

The Trace attribute indicates whether tracing is enabled. A value of true turns tracing on. The default is false .

Tracing

ASP.NET provides extensive tracing capabilities. Merely setting the Trace attribute for a page to true will cause trace output generated by ASP.NET to be sent to the browser. In addition, you can output your own trace information using the Write method of the TraceContext object, which is obtained from the Trace property of the Page .

The page HelloTrace.aspx illustrates using tracing in place of writing to the Response object.

 <!-- HelloTrace.aspx -->  <%@ Page Language="C#" Debug="true"  Trace = "true"  %>  <HTML>  <HEAD>   <SCRIPT RUNAT="SERVER">  protected void cmdEcho_Click(object Source, EventArgs e)  {     lblGreeting.Text="Hello, " + txtName.Text;  }  protected void Page_Init(Object sender, EventArgs E)  {  Trace.Write("Page_Init<br>");   Trace.Write("txtName = " + txtName.Text + "<br>");   Trace.Write("lblGreeting = " + lblGreeting.Text +   "<br>");  }  ... 

Figure 10-10 shows the browser output after the initial request for the page. Notice that the trace output is shown after the form, along with trace information that is generated by ASP.NET itself.

Figure 10-10. Browser output showing trace information.

graphics/10fig10.gif

for RuBoard


Application Development Using C# and .NET
Application Development Using C# and .NET
ISBN: 013093383X
EAN: 2147483647
Year: 2001
Pages: 158

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