Let's now get into some meat. If we look at MSDN - ASP.NET Page Life Cycle Overview
we learn that there are a number of events that occur each time a page
is loaded/refreshed/post-back. To understand this, I wrote an
application to trace what actually goes on. Here's the general run-down.
- (Obviously) the user requests a page.
- IIS determines what application the page maps to (assuming an ASPX page). If the application is currently not running, then:
- Application is loaded
- Application_Start of Global.asax is called (this is in response to an application start event).
- If the request is not yet associated with a session, or associated with a stale session, and session state is required, then:
- Session state is obtained
- Session_Start of Global.asax is called.
- A new object instance of the page class is created (so no, member fields do not retain their values).
- Page controls are created (CreateControlCollection and AddedControl).
- Post-back mode is determined (DeterminePostBackMode).
- OnPreInit is called (firing PreInit event)
- OnInit is called (firing Init event). This is a good time to add any page assertions / reject pages.
- OnInitComplete is called (firing InitComplete event). Watch the
next few steps. After OnInitComplete, page state is loaded. If you have
dynamically created page content, then that exact same
page content must be re-created at this point to ensure view state is
correctly loaded for it. That is, the set of controls for the page must
match the set of controls that view state was saved for, even if it's
not the desired set of controls for this iteration of the page.
- Page state is loaded (LoadPageStateFromPersistenceMedium is called)
- Any additional child controls are created / initialized
(EnsureChildControls is called) - EnsureChildControls should be manually
called if required at any time before Page_Load(). Think about these
two steps for a moment. Before OnPreLoad is called, all the controls of
the page are populated. To achieve this, much activity can occur after
OnInit including loading data from a database.
- OnPreLoad is called (firing PreLoad event).
- OnLoad is called (firing Load event, and thereby calling
Page_Load). Note that if a page has a template, the Page_Load on the
page is typically called before Page_Load on the template).
- Page validation is called if requested by any controls.
Manually call Validate if validation required before a control demands
it (i.e. don't rely on this).
- Page event handlers (e.g. Click event) are called at this time.
- OnLoadComplete is called (firing LoadComplete event).
- EnsureChildControls is called again to ensure any additional controls are created/initialized.
- OnPreRender is called (firing PreRender event). This is the
ideal time to perform irreversible control changes prior to rendering.
- SaveViewState is called to determine any view state that needs to be saved to the page.
- SaveStateComplete event is called at this time (even though the page has not yet been rendered).
- CreateHtmlTextWriter is called to obtain the context required to render a page.
- Render is called to perform actual page rendering.
- OnUnload is called to indicate the Page object is no longer
required. This does not necessarily indicate the page has been rendered,
and definitely does not indicate that the client has received the page.
There are some surprises here. In particular, I've found that I
generally use the "OnInit", "OnLoad", and "OnPreRender" page events.
- OnInit
- Ensure all app specific page assertions are done by this point. For
example, on one project I use this point in time to determine if the
site is actually "online" or not, and if not, redirect to some special
page.
- Ensure controls match up with previous page state prior to a postback ready to receive view state. The override "EnsureChildControls" is actually the correct place to do this.
- OnLoad (more specifically "Page_Load")
- Any code that must execute prior to control event handling.
- PreRender
- Setting up the final page look, particularly for any generated
controls. I used to do this in response to OnLoad and control event
handling, to much pain since not all of the control events are handled
at that time. PreRender is a nice choice as there will be no more events
before the actual page rendering.
If an unhandled exception is thrown, the normal page flow above is aborted, and the following occurs:
- OnError is called (firing Error event).
- OnUnload is called. The page is effectively thrown away at this point.
- Application_Error (in Global.asax) is called to handle the error and redirect to the error page.
Next week, I'll go into some more interesting events outside of the
page, but still part of the page life-cycle, to allow for example, page
redirection.
If anyone is interested, I'll post the code I used to analyze the page events.
Reference:http://it.toolbox.com/blogs/codesharp/console-to-web-3-page-life-cycle-20597