One of the biggest differences between classic ASP and ASP.NET is the execution model. In classic ASP, pages were executed in a top-to-bottom fashion. In other words, with the exception of detours to execute functions defined in the page, classic ASP pages were procedural rather than event-driven, like Visual Basic programs.
ASP.NET changes that by bringing event-driven programming to Web development through server controls and postbacks. At runtime, the code in a Web Form, as well as in any code-behind class associated with that Web Form, is compiled into an assembly. When executed, the code in that assembly fires events that you can handleboth those exposed by the Page class and those that are fired by server controls that have been added to the page.
A Web Forms page goes through the following processing stages:
Init Page and control settings are initialized as necessary for the request.
LoadViewState Server control state that was saved to viewstate in an earlier request is restored.
LoadPostData Any data returned in server control form fields is processed, and the relevant control properties are updated.
Load Controls are created and loaded, and control state matches the data entered by the client.
RaisePostDataChangedEvent Events are raised in response to changes in control data from the previous request to the current request.
RaisePostBackEvent The event that caused the postback is handled, and the appropriate server-side events are raised.
PreRender Any changes that need to be made prior to rendering the page are processed. Any processing after this point will not be rendered to the page.
SaveViewState Server control state is saved back to the pages viewstate prior to tearing down the controls.
Render Control and page output is rendered to the client.
UnLoad The page and its constituent controls are removed from memory on the server.
Of these stages, you can add page-level event handlers for the Init, Load, PreRender, and UnLoad events. These handlers are typically named Page_Init, Page_Load, Page_PreRender, and Page_UnLoad. For other stages, such as the LoadViewState, SaveViewState, and Render stages, you can override the appropriate method to customize the processing of these stages. Overriding these methods is discussed in Chapter 10.
Some events, such as those fired by the page, are fired automatically as certain stages of page processing occur. Others, such as those associated with server controls, are actually triggered on the client (such as a user clicking a button server control) but are fired and handled on the server when the page is posted back to the server. Because the page is reloaded and the control state is restored with each postback, to the client it appears as though the page is there throughout the clients interaction with it, and the application appears to operate much like a Visual Basic formbased application.
Each stage in the processing of a Web Forms page fires an event that allows you to perform processing of your own during that stage. While you might not have realized it, youve already learned how to take advantage of these event handlers in your own pages. When you double-click an empty area of a Web Form in Design view, the IDE opens the code-behind module for the Web Form and places the cursor in the Page_Load event handler, which is added to the code- behind module when the Web Form (and its associated code-behind module) is added to the project. By default, Visual Studio .NET also adds a handler for the Page_Init event to the code-behind module, but this event handler is hidden using the # Region#End Region keywords. The following illustration shows the code contained within the Web Form Designer Generated Code region in CompoundProgrammatic.aspx.cs:
You can handle other page events, such as the Page_Unload event, by adding the appropriate handler code to the code-behind module.
private void Page_UnLoad(object sender, System.EventArgs e // Event handling cod }
Of course, you can also handle events if youre not using code-behind by adding the appropriate event handler to a server-side script block within the .aspx page:
<script runat="server"> public void Page_Load(object sender, System.EventArgs e // Event handling cod </script>
Important |
The preceding code assumes that the AutoEventWireup attribute of the page has been set to true. For pages created outside of Visual Studio .NET, you wont need to set this attribute manually, since true is the default setting inherited from the <pages> configuration section in Machine.config. However, pages created in Visual Studio .NET have the AutoEventWireup attribute in their @ Page directive set to false. This means that all event handlers in these pages must be manually wired to the events that they are to handle. Youll learn more about manually wiring events in Chapter 8. |
As with events exposed by the Page class, youve already seen many examples of handling control events in this and other chapters. Handling the default event for a given control is as simple as double-clicking the control in Visual Studio .NETs Design view. Visual Studio .NET then takes care of adding the appropriate event handler to the code-behind module for the page, and wiring it up using the Handles keyword. For example, if you were to double-click the DropDownList control in the Compound.ascx control in Design view, Visual Studio .NET would add the following code to Compound.aspx.cs:
private void DropDownList1_SelectedIndexChanged(object sender System.EventArgs e }
You can add handlers for other events associated with a control by using similar syntax. When writing the event handler in code-behind, it doesnt matter what you name the event-handling procedure, as long as you properly add the event handler, like Visual Studio .NET does when it adds the Page_Load handler to the InitializeComponent event handler, as in this example:
this.Load += new System.EventHandler(this.Page_Load);
Still, its a good idea to stick with the naming convention of ControlName_EventName, as this makes it easy to tell at a glance which control and event a given procedure is handling.
Tip |
When adding event handlers in a code-behind module, an easy way to make sure that your code is correct is to use the drop-down list boxes at the top of the code editor window. Simply select the control whose event you want to handle in the left-hand drop-down list, and then select the event you want to handle from the right-hand drop-down list (events are denoted by a lightning-bolt icon). Visual Studio .NET will automatically insert the code for the event handler into your code-behind module. |
Handling control events in pages that do not use code-behind is fairly straightforward. There are two steps: First, add an event handler procedure to a server-side script block in the page. Then, map the event raised by the control to the event handler using an attribute on the control tag.
For example, if you wanted to handle the Click event of a Button control named Button1, you would add the following code to the <script> block in ServerControls.aspx:
public void Button1_Click(object Sender,System.EventArgs e // Event handler cod }
And then you would add the following attribute to the Button1 server control tag:
<asp:Button id="Button1" onClick="Button1_Click" runat="server"/>
Again, you are not required to name the event handler procedure with the ControlName_EventName naming convention, but using this convention will make your code easier to read.
While using structured exception handling might be useful for catching exceptions that are expected (see Chapter 3), at times youll want to handle errors at the page level. This is possible through a special event handler called Page_Error. The Page_Error event is raised whenever a page encounters an unhandled exception. Within the Page_Error event handler, you can examine the exception that occurred by using the Server.GetLastError method and take appropriate action or display a friendly message to the user.