Web Forms Programming Model


Sams Teach Yourself ASP.NET in 21 Days, Second Edition
By Chris Payne
Table of Contents
Day 5.  Beginning Web Forms

Web forms pages are divided into two parts: the visual elements and the accompanying UI logic. These two components are completely separate from each other conceptually, and they can be physically located anywhere you want. Typically, both parts are contained within one .aspx file. Listing 5.2 shows an example Web form.

Listing 5.2 A Typical Web Forms Page
 1:    <%@ Page Language="VB" %> 2: 3:    <script runat="server"> 4:       Sub tbMessage_Change(Sender As Object, E As EventArgs) 5:          lblMessage.Text = "Hello " + tbMessage.Text 6:       End Sub 7:    </script> 8: 9:    <html><body> 10:       <font size="5">Sam's Teach Yourself ASP.NET in 21 Days: 11:       Day 2</font><hr><p> 12:       <% Response.Write("Our First Page<p>") %> 13: 14:       <form runat="server"> 15:          Please enter your name: 16:          <asp:textbox  17:             OnTextChanged="tbMessage_Change" 18:             runat=server/> 19:          <asp:button  Text="Submit" 20:             runat=server/><p> 21:          <asp:label  font-size="20pt" 22:             runat=server/> 23:       </form> 24:    </body></html> 


This should look familiar it's the example you looked at on Day 2. The UI is contained within the HTML portion of the page, consisting of the server controls on lines 16, 19, and 21. These controls have properties, methods, and events that you can control. The UI logic the code that controls the UI is contained in the code declaration block on lines 3 7.

There's nothing exotic about creating Web forms. Any ASP.NET page that contains server controls and UI logic is a Web form. Let's take a look at some of the pieces that make up Web forms.

Server Controls

As discussed previously, server controls are the user interface elements of a Web form. There are four types of server controls in ASP.NET: HTML server controls, Web controls, validation controls, and user controls. HTML server controls represent the normal HTML form elements, such as text input boxes and buttons, but they're created on the server, where you can control them. Web controls are similar, but they provide more functionality and can represent more complex user interfaces. Validation controls are used to validate user input, and user controls are custom-built controls that perform some piece of functionality. All of these controls will be covered today and tomorrow, except for validation controls, which will be covered on Day 7, "Validating ASP.NET Pages."

All server controls have properties, methods, and events. They provide much more functionality than traditional HTML form elements, and they make it easier for the developer to build user interfaces.

When you build a server control, you don't have to worry about writing HTML. When the page is requested, server controls automatically spit out the HTML that will produce the proper display. For example, the following line creates a Button server control on the server:

 <asp:Button text="Submit" runat="server" /> 

When this button is requested, it spits out the following HTML to the client:

 <input type="submit" name="ctrl1" value="Submit" /> 

The two lines barely resemble each other. The first line is used only by the server the client never sees it. (And if it did, the browser wouldn't know what to do because it only understands HTML.) The second line is what the client sees. By building controls this way, you can spend less time worrying about the HTML that will provide the UI layout, and more time thinking about what your UI should do.


Also, ASP.NET knows the capabilities of each browser, so it sends the appropriate HTML to each one. For example, if a browser doesn't support Dynamic HTML (DHTML), ASP.NET won't send it any. This is known as down-level support because ASP.NET can tone down the HTML output for browsers that don't support higher-level functionality.


Ideally, down-level support will render everything properly for every control. In reality, you aren't so lucky. Some elements will have problems rendering on different browsers because not all browsers treat HTML the same. When you're developing for the major browser versions, though, down-level support will function properly. (Most of the time!)

Server Control Events

Server controls generate multitudes of events. In other words, there are a lot of things a user can do to a server control: click on a button, click a link, fill out a text box, select an item in a list box, and so on. All of these events must be handled by the server, so every time an event occurs, the client posts data to the server.


It's important to distinguish passive user events from active events. An active event is one that requires an explicit user action meaning the user must intentionally perform the action. This includes clicking a button or a link, filling out a text box, and so on. A passive event is one that can be performed without the user's direct intention, such as moving the mouse cursor over an image.

Only active events are handled on the server there are too many passive ones to reliably post all that data back to the server. However, you can still handle these with client-side script.

There are two ways events are posted to the server: immediately as they occur, or collectively during a single post. The latter is a bit more efficient because you don't have to send as many posts, which means that less data is traveling back and forth between the client and server.


In many cases, you'll want to use the latter method. For example, imagine a user typing his name into a form. Every time he types a letter, an event occurs. You wouldn't want to post data every time a letter changes, but only when the user has finished entering the data or clicks the Submit button. Events like this are cached, meaning they're stored up on the client until the user decides to post the data. At that point the server can evaluate them one at a time.


Actually, this event, known as the TextChanged event, only happens when the user enters some text and leaves that UI element (that is, uses the Tab key to move to another element). But the idea is the same.

You can force these events to be posted to the server immediately, as you'll see in "Posting Data Immediately" later today.

As discussed on Day 3, "Using Visual Basic.NET and C#," all server control events in ASP.NET send two pieces of data as parameters to the server: an object that represents the control that generated the event, and an object that describes any specific information about the event.

Figure 5.3. The server control sends information describing itself and any specific information about the event.


Controls automatically generate events whenever something happens. To handle the event on the server, you need to tell the control what method to use. For example, the following tells ASP.NET to execute the ClickHandler method on the server upon the occurrence of the Click event:

 <asp:Button runat="server" OnClick="ClickHandler" /> 

This method could look like the following:

 1:    sub ClickHandler(Sender as Object, e as Eventargs) 2:       do something... 3:    end sub 

As mentioned on Day 3, line 1 shows the standard event parameter list for ASP.NET server controls. The second parameter can vary depending on the type of event that has occurred. Most of the time, you'll be using this standard parameter list.

For example, let's look at the example in Listing 5.3.

Listing 5.3 An Event Handler
 1:    <%@ Page Language="VB" %> 2: 3:    <script runat="server"> 4:       Sub Button1_Click(Sender as Object, e as EventArgs) 5:          Label1.Text="You clicked <b>" & Sender.Text & "</b>" 6:       end Sub 7:    </script> 8: 9:    <html><body> 10:       <font size="5">Sam's Teach 11:       Days: Day 5 </font><hr><p> 12: 13:       <form runat="server"> 14:          <asp:Button id=Button1 runat="server" Text="Button1" 15:             onClick="Button1_Click" /> 16:          <p> 17:          <asp:Label id=Label1 runat=server /> 18:       </form> 19:    </body></html> 

When you click on the button, the code should produce the output shown in Figure 5.4.

Figure 5.4. The page produced by Listing 5.3.



Even though you haven't looked at the server controls yet, you can see that the Button control on line 14 has a Click event. This event posts information to the server and executes the Button1_Click method, which is defined in the code declaration block on lines 4 6.


Don't forget to include runat="server so that the server controls will work properly.

Also, note that the <form> tag is required here. Without it, none of the data would be posted to the server and the page wouldn't work.

Let's take a look at line 5 in particular:

 5:    Label1.Text = "You clicked <b>" & Sender.Text & "</b>" 

This line sets the Text property of the control named Label1 (the Label on line 17) to whatever is specified after the equal sign. Sender is the name of one of the parameters. Since you know it represents the Button, you can grab its Text property as well.

Looking down to line 14, you see that the Button's text property is set to Button1. The following line could be used to produce the same output:

 Label1.Text="You clicked <b>" & Button1.Text & "</b>" 

But let's take a look at the C# version of line 5:

 5:    Label1.Text = "You clicked <b>" + ((Button)Sender).Text + "</b>"; 

Aside from the regular syntactic changes, there is one other change you must make from VB.NET. Recall that VB.NET is forgiving in the way it casts variables VB.NET automatically casts some data types for you. C# does not.

Note that the Sender variable is passed in as an Object data type rather than a Button. The Object data type does not have a property called Text, though the Button data type does. If you try to use Sender.Text in C#, you would get an error. VB.NET would automatically cast the Object to a Button so that you could access the Text property. C# won't do this for you, so you need to explicitly cast the Sender variable as a Button. This is done by prefixing the variable name with type of data you want to convert to (see Day 3 for more information on casting). As long as you remember to explicitly cast your variables (which you should do regardless of the language you use), you'll be fine.

The second parameter in your method, e, currently doesn't contain any information because the Button control had nothing else to send. However, you need to include it anyway because it's part of the standard event parameter list.

Thus, you can handle events however you want. Events will keep occurring, and you can easily provide the methods to handle them. You can just leave the event handler out for the events that you want to ignore. Also, this method allows you to have one method that can handle many different events. There's nothing stopping you from creating 20 Button controls that all reference the same method.


Let's say you specify in the server control that a method should handle an event:

 <asp:Button runat="server" OnClick="SomeMethod" /> 

If you don't create the SomeMethod method somewhere in your code declaration block, you'll receive an error.

Posting Web Forms

Let's imagine a typical ASP.NET scenario. When the page loads into the browser, you display a welcome message in a server control. This message becomes part of the control's viewstate, and ASP.NET automatically remembers it.

Then the user submits the form, or an event occurs that causes a post to the server. The server then processes any data or events it needs to, and then it sends the page back to the client for display.

Since ASP.NET remembers the viewstate for the control, it automatically fills in the welcome message again without any intervention from you! This is the same for user-entered information. If a user enters her name in a text box, she'll find that the text she entered stays in the text box even after the form is submitted. This is a welcome change from traditional HTML forms, where the values were lost upon every post.

Because of this, you don't need to refill the server controls' values after the form is posted. ASP.NET does it for you.

As mentioned on Day 4, "Using ASP.NET Objects with C# and VB.NET," the Page object has a property called IsPostBack that tells you whether or not the form has already been posted. You can check this property and decide whether or not to fill in server controls. For example, let's take a look at Listing 5.4.

Listing 5.4 Checking the IsPostBack Property
 1:    <%@ Page Language="C#" %> 2: 3:    <script runat="server"> 4:       void Page_Load(Object Sender, EventArgs e) { 5:          if (!Page.IsPostBack) { 6:             lblMessage.Text = "Hello world!!!!"; 7:          } 8:       } 9: 10:       void Submit(Object Sender, EventArgs e) { 11:          lblMessage2.Text = "Form posted"; 12:       } 13:    </script> 14: 15:    <html><body> 16:       <form runat="server"> 17:          <asp:Button  runat="server" Text="Submit" 18:             onClick="Submit" /> 19:          <p> 20:          <asp:Label  runat=server /> 21:          <p> 22:          <asp:Label  runat=server /> 23:       </form> 24:    </body></html> 


When this page loads, the words "Hello World!!!!" will be displayed in the label on line 20. When the user clicks the Submit button, "Form posted" will appear in the second label on line 22. The first label will still have the hello message because ASP.NET saves it in the viewstate and automatically fills it in for you.

On line 5, you check the IsPostBack property, and if it's true (meaning the form has been submitted), you don't execute line 6. You won't have to refill the label every time the form is posted because ASP.NET does it for you. Figure 5.5 shows the output from this code after the form has been posted.

Figure 5.5. The text in the label stays there even though the form is submitted and you don't explicitly fill it yourself.


This was just a simple example, and not processing line 6 isn't going to save you a lot of time. But as the commands get more and more complex, checking IsPostBack will become very useful.

Saving State

As you know, Web forms save the viewstate of each control in the form through hidden form fields. This viewstate tells you what is entered in the control (if anything), whether the control is selected or not, which item is selected, and so on. The viewstate provides a lot of information that ASP.NET uses to maintain the state of each server control.

There is another way to save information in Web forms, though. You can use the state bag, an object that holds values when a form is posted. When you place something in the state bag and submit the form, the server saves the information and sends it back to the client after it's finished processing. This is an easy way to store custom information that a user didn't enter, such as a calculation. You can access the state bag through the ViewState variable.

Let's look at an example. Listing 5.5 saves the current time in the state bag as soon as the page is loaded. When the user clicks the Submit button, you compare the start time to the new time.

Listing 5.5 Saving Values in the State Bag
 1:    <%@ Page Language="VB" %> 2: 3:    <script runat="server"> 4:       Sub Page_Load(Sender as Object, e as EventArgs) 5:          if not Page.IsPostBack then 6:             ViewState("StartTime") = DateTime.Now 7:             lblMessage.Text = "The time is now: " & _ 8:                ViewState("StartTime") 9:          end if 10:       end sub 11: 12:       Sub Submit(obj as object, e as EventArgs) 13:          lblMessage.Text = "The time is now: " & _ 14:             DateTime.Now & "<br>started at: " & _ 15:             ViewState("StartTime") 16:       end Sub 17:    </script> 18: 19:    <html><body> 20:       <font size="5">Sam's Teach Yourself ASP.NET in 21 21:       Days: Day 5 </font><hr><p> 22: 23:       <form runat="server"> 24:          <asp:Button  runat="server" Text="Submit" 25:             onClick="Submit" /> 26:          <p> 27:          <asp:Label  runat=server /> 28:       </form> 29:    </body></html> 


You want to store the time of the first viewing of the page, so you check the IsPostBack property on line 5 in the Page_Load event handler. If this is the first viewing, you store the current time (as denoted by DateTime.Now) in ViewState. ViewState is the name of the state bag that ASP.NET creates for you. Interacting with it is exactly the same as interacting with the Session object from yesterday. You then display this time in a label control.

Whenever the user clicks the Submit button, the Submit method is executed. This method, beginning on line 12, displays the current time and the time stored in the state bag in the label. Figure 5.6 shows the output from this listing. The value from the state bag is different from the current value.

Figure 5.6. The state bag holds the time of the first viewing.



Unlike the Session or Application objects, the state bag is emptied as soon as the user leaves the page. The values are saved only as long as the same form is posted over again. Once a new page is loaded, the state bag is discarded.

Do Don't
Do use the state bag when you need to save custom values for a particular form. Don't use the state bag when you need to save information for an indefinite amount of time. Instead, use the Session or Application objects, a cookie, or a database.

Web Forms Processing Order

Occasionally, you'll need to process pages in a particular order. For instance, you may not want to display a message until after an event has been handled. This will become especially important as you examine databases in Week 2. Thus, it's helpful to know the order in which Web forms are processed:

  1. The page is requested (or posted).

  2. The viewstate is restored for any controls.

  3. The Page_Load event occurs.

  4. Events are handled (that is, the methods that handle events are called). Any events that were cached are handled first, followed by the event that posted the form. If multiple events are raised at once, they're processed in no particular order.

  5. The Page_Unload event occurs.

The process is initiated by a user requesting the page. ASP.NET then restores the state of every control on the page and fires the Page_Load event, which may or may not be handled with an event handler. Any events that have occurred are then handled by developer-defined functions. Finally, the Page_Unload event fires and releases any memory that doesn't need to be tied up. You'll become very familiar with this process as you develop more Web forms.


    Sams Teach Yourself ASP. NET in 21 Days
    Sams Teach Yourself ASP.NET in 21 Days (2nd Edition)
    ISBN: 0672324458
    EAN: 2147483647
    Year: 2003
    Pages: 307
    Authors: Chris Payne

    Similar book on Amazon

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