Introduction
After reading this article, you will be able to answer questions like:
- What is the sequence of Page Events?
-
What are events and what are methods in Page Life Cycle?
- What is the page event on which you can access view state? OR What is the page event on which you can access property of control?
- If I have a Page which has a master page and a user control, what will be the sequence of Load, init, etc.?
- On which event can you add controls, master page, theme to the page earliest?
What is the practical need to know sequences of event in ASP.NET Page life cycle?
Consider a scenario where you have a Page named Home.aspx, with user control named Control.ascx, and a Master Page. You are modifying something in the session, on all these three but in certain order like adding product ID to session from the page when user picks some listed product, checking on the Master page if the user has permission to view a particular product on that page, and opening the detail of product in the user control. To perform these kind of operations, it is essential for you to know the sequence of execution.
Let us do a quick experiment and let these three (Page, master, user control) tell the sequence.
You will create a web page, with a user control and master page. In three of these, you will describe the page events like Page_Load
, Page_PreInit
, etc., where the name of corresponding event will be stored inside a session variable and later the value inside session variable will be written off to the page.
Using the Code
- Create an empty ASP.NET web project.
- Add two master pages
Old.master
, New.master
. Add a label inside New.master
with ID "lblMaster
". - Add a page named Home.aspx assign it
Old.master
. Put a panel inside it with ID "pnlMain
". Drop a label on Page named "lblHead
". - Add an user Control named "Control.aspx". Put a label inside it which identifies the control on the page, for example : "Hi from User Control !".
- Add a skin file named "MyTheme". Do a simple styling of
Label
control there by adding the following line of code:
<asp:Label runat="server" BackColor="White" ForeColor="Blue">
</asp:Label>
Following are the page events we are going to encounter:
Page_PreInit
Page_Init
Page_InitComplete
Page_PreLoad
Page_Load
Page_LoadComplete
Page_PreRender
Page_PreRenderComplete
Page_SaveStateComplete
Render
Unload
Among these, Render
is a method which gets executed for each control, and also for page.
The unload
method comes already implemented in the complementer page class, which we can override.
Session
is something that is accessible to all of these events starting from "PreInIt
" to "OnUnload
". But "SaveStateComplete
" is the last event which can modify the "Response
". Following lines of code store the event names inside session
and write the session
value to response, paste the code inside the code behind file:
protected void Page_Load(object sender, EventArgs e)
{
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> Page_Load";
ViewState["E"] = Convert.ToString(ViewState["E"]) +
"<br/> Page_Load";
}
protected void Page_PreInit(object sender, EventArgs e)
{
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> Page_PreInit";
if (!IsPostBack) {
Page.MasterPageFile = "New.Master"; Label lblMas = (Label)Page.Master.FindControl("lblMaster");
lblMas.Text = "<br/> I am the master page ,
I was set from Page_PreInit event dynamically,
I am blue because of dynamic theme applied to me";
Label lblNew = new Label();
lblNew.Text = "<br/> I am the control added Dynamically in Page_PreInit,
I am blue because of dynamic skin applied to me,
these properties can be overridden in further page events.";
pnlMain.Controls.Add(lblNew); Page.Theme = "MyTheme"; ViewState["E"] = Convert.ToString
(ViewState["E"]) + "<br/> Page_PreInit";
}
else
{
if (Convert.ToString(ViewState["E"]) == string.Empty)
ViewState["E2"] = "<br/> <br/>
Page Posted Back <br/> Nothing here in view State Page_PreInit";
else
ViewState["E2"] = Convert.ToString(ViewState["E"]) +
"<br/> <b> View State found in Page_PreInit</b>";
}
}
protected void Page_Init(object sender, EventArgs e)
{
if (!IsPostBack)
{
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> Page_Init";
Label lblNew = new Label();
lblNew.Text = "<br/>
I am the control added Dynamically from preinit.";
pnlMain.Controls.Add(lblNew);
ViewState["E"] =
Convert.ToString(ViewState["E"]) + "<br/> Page_Init";
}
else
{
if (Convert.ToString(ViewState["E"]) == string.Empty)
ViewState["E2"] = Convert.ToString(ViewState["E2"]) +
"<br/>" + "<br/> Nothing here in view State Page_Init";
else
ViewState["E2"] = Convert.ToString(ViewState["E2"]) +
Convert.ToString(ViewState["E"]) + "<br/>
<b> View State found in Page_Init</b>";
}
}
protected void Page_InitComplete(object sender, EventArgs e)
{
if (!IsPostBack)
{
Session["E"] =
Convert.ToString(Session["E"]) + "<br/> Page_InitComplete";
Label lblNew = new Label();
lblNew.Text = "<br/>
I am the control added Dynamically from init complete.";
pnlMain.Controls.Add(lblNew);
ViewState["E"] = Convert.ToString(ViewState["E"]) +
"<br/> Page_InitComplete";
}
else
{
if (Convert.ToString(ViewState["E"]) == string.Empty)
ViewState["E2"] = Convert.ToString(ViewState["E2"]) +
"<br/>" + "<br/>
Nothing here in view State Page_InitComplete";
else
ViewState["E2"] = Convert.ToString(ViewState["E2"]) +
Convert.ToString(ViewState["E"]) + "<br/> <b>
View State found in Page_InitComplete</b>";
}
}
protected void Page_PreLoad(object sender, EventArgs e)
{
if (!IsPostBack)
{
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> Page_PreLoad";
ViewState["E"] = Convert.ToString(ViewState["E"]) +
"<br/> Page_PreLoad";
}
else
{
if (Convert.ToString(ViewState["E"]) == string.Empty)
ViewState["E2"] = Convert.ToString(ViewState["E2"]) +
"<br/>" + "<br/>
Nothing here in view State Page_PreLoad";
else
ViewState["E2"] = Convert.ToString(ViewState["E2"]) +
Convert.ToString(ViewState["E"]) + "<br/>
<b> View State found in Page_PreLoad</b>";
}
}
protected void Page_LoadComplete(object sender, EventArgs e)
{
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> Page_LoadComplete";
ViewState["E"] = Convert.ToString(ViewState["E"]) +
"<br/> Page_LoadComplete";
}
protected void Page_PreRender(object sender, EventArgs e)
{
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> Page_PreRender";
ViewState["E"] = Convert.ToString(ViewState["E"]) +
"<br/> Page_PreRender";
}
protected void Page_PreRenderComplete(object sender, EventArgs e)
{
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> Page_PreRenderComplete";
ViewState["E"] = Convert.ToString(ViewState["E"]) +
"<br/> Page_PreRenderComplete";
}
protected void Page_SaveStateComplete
(object sender, EventArgs e) {
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> Page_SaveStateComplete";
ViewState["E"] = Convert.ToString(ViewState["E"]) +
"<br/> Page_SaveStateComplete";
Response.Write("<br/><br/><br/><b>Session State</b>" +
Convert.ToString(Session["E"])+"<br/><b>Session State</b>");
Response.Write("<br/><b>View State</b>" +
Convert.ToString(ViewState["E"]));
Response.Write("<br/><b>View State</b>" +
Convert.ToString(ViewState["E2"]));
}
protected void btnPostBack_Click(object sender, EventArgs e)
{
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> Control Event";
}
protected override void OnUnload( EventArgs e)
{
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> Page Unload";
}
This page also contains some of the lines for further experiment with Post Back, just go through the code and run the page, you will see all the page events stored in session
and ViewState
in the following sequence:
-
Page_PreInit
-
Page_Init
-
Page_InitComplete
-
Page_PreLoad
-
Page_Load
-
Page_LoadComplete
-
Page_PreRender
-
Page_PreRenderComplete
-
Page_SaveStateComplete
Also user control and master page will be there with skin applied, the label we have put there will show the following text (in blue):
I am the master page, I was set from Page_PreInit event dynamically, I am blue because of dynamic theme applied to me.
Hi from User Control !
I am the control added Dynamically in Page_PreInit, I am blue because of dynamic skin applied to me, these properties can be overridden in further page events.
I am the control added Dynamically from preinit.
I am the control added Dynamically from init complete.
Render
and Unload
will execute after these events, so even if the value we set in session
during unload
is there, it will only appear in the next post back as "Response
" object is out of context in "OnUnload
".
Based on the output, you can deduce the following:
A. Master page and Theme, web control can be added dynamically on Page_PreInit
, earliest.
Drop the User Control to the page.
Go to user control's code behind and store each event name inside the session by adding the following lines of code:
protected void Page_Load(object sender, EventArgs e)
{
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> User Control Page_Load";
}
protected void Page_PreInit(object sender, EventArgs e)
{
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> User Control Page_PreInit";
}
protected void Page_Init(object sender, EventArgs e)
{
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> User Control Page_Init";
}
protected void Page_InitComplete(object sender, EventArgs e)
{
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> User Control Page_InitComplete";
}
protected void Page_PreLoad(object sender, EventArgs e)
{
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> User Control Page_PreLoad";
}
protected void Page_LoadComplete(object sender, EventArgs e)
{
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> User Control Page_LoadComplete";
}
protected void Page_PreRender(object sender, EventArgs e)
{
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> User Control Page_PreRender";
}
protected void Page_PreRenderComplete(object sender, EventArgs e)
{
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> User Control Page_PreRenderComplete";
}
protected void Page_SaveStateComplete(object sender, EventArgs e)
{
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> User Control Page_SaveStateComplete";
}
protected override void OnUnload( EventArgs e)
{
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> User Control Unload";
}
Go to new master and add the same code in its code behind there, just change the prefixes of values stored in session to 'Master Page' instead of 'User control'.
Now run the page, you will see the following output:
-
Page_PreInit
-
User Control Page_Init
-
Master Page Page_Init
-
Page_Init
-
Page_InitComplete
-
Page_PreLoad
-
Page_Load
-
Master Page Page_Load
-
User Control Page_Load
-
Page_LoadComplete
-
Page_PreRender
-
Master Page Page_PreRender
-
User Control Page_PreRender
-
Page_PreRenderComplete
-
Page_SaveStateComplete
You can see that:
B. Page_Load
, pre_Render
event sequence of Home Page, Master Page, User Control are opposite of Page_Init event.
C. Preinit
, Initcomplete
, loadComplete
, prerenderComplete
, saveStateComplete
are called once only from the Page, not from the User Control or Master page.
Now add a Button web user control to the Page, handle its click event by adding the following one line of code:
Session["E"] = Convert.ToString(Session["E"]) +
"<br/> Control Event";
Click the button and following is the successive output:
User Control Unload
Master Page Unload
Page Unload
Page Posted Back
Nothing here in view State Page_PreInit
Nothing here in view State Page_Init
Nothing here in view State Page_InitComplete
Page_PreInit
Page_Init
Page_InitComplete
Page_PreLoad
Page_Load
Page_LoadComplete
Page_PreRender
Page_PreRenderComplete
View State found in Page_PreLoad
You will find out:
D. Pre_Load
is the first event where you will get the ViewState
restored.
Clicking the button also writes the lines stored during Unload event of previous request because:
E. "Response
" object is out of context in unload.
This code is also attached with the code name Delta.
Points of Interest
By debugging these code snippets and bringing some other incident like DataBinding
, databaseConnection
, Configuration Access, Application State in the scene, you can find out more interesting results.
History
- 26th November, 2014: Initial version