What calls Page_Load and how does it do it? - asp.net

Page_Load isn't a virtual method. What calls this method and how does it do it? Is it reflection or some other technique? Also how many events are handled this way?
Also is it preferable to handle things in an overloaded OnLoad or Page_Load? How are they different?

ASP.NET has a feature called "AutoEventWireup" - this feature allows you to create methods that have the EventHandler signature with names like Page_Load and the runtime will wire up the event from the parent page to the method in your class. Basically the runtime does this on your behalf:
this.Load += this.Page_Load;
Now it is better to disable AutoEventWireup and either create these event handlers yourself in the pages OnInit method or simply override the parent page's OnLoad method.
Edit (in response to the OP's comment below): This process doesn't cover button clicks and such but the process is similar.
In order for a method like MyButton_Click to work without you explicitly creating an event handler you would have to set the OnClick attribute on the control in the aspx file like this:
<asp:button
id="MyButton"
onClick="MyButton_Click"
runat="server" />
This would prompt ASP.NET to create the button click delegate for you and attach it to the button's Click event.

The order in which the virtual methods (OnLoad) and event handlers (Page_Load) are called is defined by the so called page lifecycle. This is just the way how the ASP.NET runtime processes an incoming request (e.g. with the Init, Load, Render stages).
You can use either OnLoad or Page_Load but you have to be aware of what happens:
inside OnLoad you must call base.OnLoad
inside base.OnLoad the Load event will be raised
Page_Load is a handler for the Load event (which is automatically wired-up) and will therefore be invoked as a result of the Load event that's being raised.
If you do not call base.OnLoad in your OnLoad override, then the Load event will not be raised.
Update: you can use an empty page with the following code-behind to see what happens:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
base.Load += new EventHandler(My_Page_Load);
}
void My_Page_Load(object sender, EventArgs e)
{
Response.Write("My_Page_Load<br/>");
}
protected override void OnLoad(EventArgs e)
{
Response.Write("Start of OnLoad<br/>");
base.OnLoad(e);
Response.Write("End of OnLoad<br/>");
}
protected void Page_Load(object sender, EventArgs e)
{
Response.Write("Page_Load<br/>");
}
Try commenting the base.OnLoad(e) call and see again.

The OnLoad method somewhere up the Page hierarchy calls the events assigned to Load (via +=).
The naming Page_Load is just a convention. In AutoEventWireUp mode (i.e. no event handler explicitly declared) this convention is used to find event handlers by their names.
If you have .Net1 available, you can see how the designer adds code to the page's OnInit() to add all components of the page and set
this.Load += new System.EventHandler(this.Page_Load);
.Net2 still does that, but in a separate file which is hidden somewhere under the Windows\Microsoft.Net\Framework\v*\Temporary ASP.Net Files.
I find this chart on ASP.Net Page Life Cycle very useful.

Take a look at the ASP.NET page lifecycle, there is a section for lifecycle events where it describes load.
Load
The Page calls the OnLoad event
method on the Page, then recursively
does the same for each child control,
which does the same for each of its
child controls until the page and all
controls are loaded. Use the OnLoad
event method to set properties in
controls and establish database
connections.
Further Quote:
Note that when creating an event
handler using the Page_event syntax,
the base implementation is implicitly
called and therefore you do not need
to call it in your method. For
example, the base page class's OnLoad
method is always called, whether you
create a Page_Load method or not.
However, if you override the page
OnLoad method with the override
keyword (Overrides in Visual Basic),
you must explicitly call the base
method. For example, if you override
the OnLoad method on the page, you
must call base.Load (MyBase.Load in
Visual Basic) in order for the base
implementation to be run.

In the page directive it says: Autoeventwireup="true"
Thats what happens, its automatically wired up to the Load event... (and some other events like PreInit, Init, Unload etc.)

Related

Is there an after Page_Load event in ASP.net

Is there an event that is triggered after all Page_Load events have completed?
How can i have more than one Page_Load?
When you have user controls.
Before my page can render, i need my page (and all embedded controls) to have initialized themselves by completing their Page_Load events.
The problem, of course, is that if i put code in my page's Page_Load handler:
MyPage.aspx
--> Page_Load
---> DoSomethingWithUserControl()
UserControl1.ascx
--> Page_Load
---> initialize ourselves now that viewstate has been restored
then i begin to access my UserControl1 control before it is ready.
i need a way to run code after all Page_Load events have fired, but before any postback events (e.g. Click events) have fired:
MyPage.aspx
--> Page_Load
UserControl1.ascx
--> Page_Load
---> initialize ourselves now that viewstate has been restored
MyPage.aspx
--> Page_AfterLoad
---> DoSomethingWithUserControl()
Looking at the page lifecycle in MSDN it looks like there is no way to raise an event after all Page_Loads have been completed:
Is there a way to raise an after after all Page_Loads have completed?
Page_LoadComplete is the event that is raised after all controls have been loaded
Remember that the Init event is first triggered by all child controls, and just when all controls have been initialized, the Init event of the page is raised. The Load event works the other way around, the page first raises the Load event and then each child control raises its own Load event. At the end the LoadComplete is raised. Note that this is true only when the controls are created at design time, when the controls are created dynamically they (sadly) do not follow this approach strictly.
From MSDN:
If controls are created dynamically at run time or declaratively within templates of data-bound controls, their events are initially not synchronized with those of other controls on the page. For example, for a control that is added at run time, the Init and Load events might occur much later in the page life cycle than the same events for controls created declaratively. Therefore, from the time that they are instantiated, dynamically added controls and controls in templates raise their events one after the other until they have caught up to the event during which it was added to the Controls collection.
Take a look:
(source: http://msdn.microsoft.com/en-us/library/ms178472.aspx)
Edit 1
In order to fulfill all your requirements:
i need a way to run code after all Page_Load events have fired, but before any postback events (e.g. Click events) have fired:
I think the easiest way is to declare a custom event in the User Control and fire it after the control has been loaded, then jus subscribe to that event in your ASPX
User Control
public event Action LoadCompleted = delegate { };
protected void Page_Load(object sender, EventArgs e)
{
this.LoadCompleted();
}
ASPX page
protected void Page_Load(object sender, EventArgs e)
{
this.myUserControl.LoadCompleted += () =>
{
// do somethign interesting
this.lblMessage.Text = DateTime.Now.ToString();
};
}
It seems that there really is no way to reliably get your code to execute between the time when all (statically declared, see Jupaols comment about dynamically added) controls are loaded and the time when their postback events are raised.
I even went so far as to disassemble the Page class using reflector and as far as I could tell, the page isn't calling any methods that you could tap into between these times.
So for the general case it seems like your just out of luck.
But your statement
then i begin to access my UserControl1 control before it is ready
is questionable. By the time the Page_Load method is called, the viewstate and control state have been set on all controls (at least the statically declared ones). So unless you have some more state initialization going on in the OnLoad method of a control, the control is ready to be tinkered with. If you DO have something going on in OnLoad, then why not do the tinkering there?

Using Page_Load and Page_PreRender in ASP.Net

I see some people are using Page_Load and Page_PreRender in same aspx page. Can I exactly know why do we need to invoke both the methods in same asp.net page?
Please see the code below,
protected void Page_Load(object sender, EventArgs e)
{
try
{
dprPager.ButtonClickPager += new EventHandler(dprPager_ButtonClickPager);
if (!Page.IsPostBack)
{
InitPager();
}
}
catch (Exception ex)
{
}
}
protected void Page_PreRender(object sender, EventArgs e)
{
erMsg.Visible = !string.IsNullOrEmpty(lblError.Text);
}
The major difference between Page_Load and Page_PreRender is that in the Page_Load method not all of your page controls are completely initialized (loaded), because individual controls Load() methods has not been called yet. This means that tree is not ready for rendering yet. In Page_PreRender you guaranteed that all page controls are loaded and ready for rendering. Technically Page_PreRender is your last chance to tweak the page before it turns into HTML stream.
It depends on your requirements.
Page Load : Perform actions common to all requests, such as setting up a database query. At this point, server controls in the tree are created and initialized, the state is restored, and form controls reflect client-side data. See Handling Inherited Events.
Prerender :Perform any updates before the output is rendered. Any changes made to the state of the control in the prerender phase can be saved, while changes made in the rendering phase are lost. See Handling Inherited Events.
Reference: Control Execution Lifecycle MSDN
Try to read about
ASP.NET Page Life Cycle Overview ASP.NET
Control Execution Lifecycle
Regards
Page_Load happens after ViewState and PostData is sent into all of your server side controls by ASP.NET controls being created on the page. Page_Init is the event fired prior to ViewState and PostData being reinstated. Page_Load is where you typically do any page wide initilization. Page_PreRender is the last event you have a chance to handle prior to the page's state being rendered into HTML. Page_Load
is the more typical event to work with.
Well a big requirement to implement PreRender as opposed to Load is the need to work with the controls on the page. On Page_Load, the controls are not rendered, and therefore cannot be referenced.
Processing the ASP.NET web-form takes place in stages. At each state various events are raised. If you are interested to plug your code into the processing flow (on server side) then you have to handle appropriate page event.
The main point of the differences as pointed out #BizApps is that Load event happens right after the ViewState is populated while PreRender event happens later, right before Rendering phase, and after all individual children controls' action event handlers are already executing.
Therefore, any modifications done by the controls' actions event handler should be updated in the control hierarchy during PreRender as it happens after.

se the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation

guys, I have a usercontrol in my asp.net 3.5 application and I am passing some plain text on button click event. button is situated in the usercontrol. but when I fire the event, I am getting the following error;
Invalid postback or callback argument.
Event validation is enabled using
in configuration or <%# Page
EnableEventValidation="true" %> in a
page. For security purposes, this
feature verifies that arguments to
postback or callback events originate
from the server control that
originally rendered them. If the data
is valid and expected, use the
ClientScriptManager.RegisterForEventValidation
method in order to register the
postback or callback data for
validation.
when I set the EnableEventValidation="false" to web form page like blow. it fires the event;
<%# Page EnableEventValidation="false" %>
but I am thinking that it shouldn't be a good idea to set that false. So, what is the alternative here? there error saying that 'use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.' but where am I gonna register that thing? thanks !
Also, I am using some AjaxControlToolkit controls inside my usercontrol and some jquery stuff.
try
if (!Page.IsPostBack)
before load and bind data in datagrid
The problem with ASP.NET 2.0 event validation is that it is all or nothing and a bit heavy handed. I read an article that explains what you should do here.
Basically you need to register the child controls of the user control with the event validation engine.
C#
protected override void Render(HtmlTextWriter writer)
{
// Register controls for event validation
foreach (Control c in this.Controls)
{
this.Page.ClientScript.RegisterForEventValidation(
c.UniqueID.ToString()
);
}
base.Render(writer);
}
VB
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
For Each aControl As Control In Me.Controls
Me.Page.ClientScript.RegisterForEventValidation(aControl.UniqueID.ToString)
Next aControl
MyBase.Render(writer)
End Sub
Now this may not solve your problem because I am not sure how you are returning the string. Another article explains that the event validation is a combination of the control's unique ID and all the values it can pass back. If you are using the command value of a button to pass the text you may have trouble with this task.
If the event that is causing the issue is the click, then registering the controls of the user control should do the trick.
In my situation I was trying to update a GridViews datasource on page_load and I forgot to check if the request was a postback, thus my source was trying to change and it threw this error. Once I did the check for post back it worked fine. Hope this helps someone in the future.
if (Page.IsPostBack == false)
{
this.sqlObj = new SqlServer(ConfigurationManager.ConnectionStrings["PdfReceiverConnectionString"].ToString());
this.populateDataGrid();
}
You can leave it enabled then register your control for event validation. Add the following call in the PreRender or Render page life cycle then your control should work without having to turn off eventValidation:
Page.ClientScript.RegisterForEventValidation(this.UniqueID);
Check your HTML, nested from Tags will also cause that

ASP.NET data binding on postback

Working on an ASP.NET 4.0 project, which uses user controls to dynamically generate a form based on definitions stored in the database. One form field would look like this:
<usc:RefControl ID="ctrlUser1"
ReferenceFieldId='product.user1'
ValidationFormat="^\d+\.?\d{0,2}$"
runat="server"/>
Behind the scenes the control emits a RegularExpressionValidator based on the RefControl.ValidationFormat property.
This works fine, however the problem is that this architecture only allows us to validate with regexes. Now I need to add date format validation, based on the user's preferences (which aren't dependent on their UICulture).
Reluctant to refactor the entire user control setup, I need to be able to pass a on-the-fly regex pattern to the ValidationFormat property. Currently I'm using a data binding expression to bind the property to a page instance method:
<usc:RefControl ID="ctrlUser2"
ReferenceFieldId='product.user2'
ValidationFormat="<%# GetUserDateValidationFormat()%>"
runat="server"/>
Code behind:
/// <summary>
/// Returns a regular expression that validates the current user's date format
/// </summary>
public string GetUserDateValidationFormat()
{
//...
}
Works okay on first page load, but on subsequent postbacks the validation doesn't work. I think the issue is that the data binding expression doesn't evaluate at all, but I'm not sure I understand why. I'm calling Page.DataBind() in Page_Init whether Page.IsPostBack or not, so shouldn't this work?
If you see I'm barking up the wrong tree, any alternative solutions to the same problem are also welcome.
EDIT
Managed to solve this problem. The issue was with the way ASP.NET page life cycle invokes the user control's events before the page's own events. The control values were being initialized before the data binding on the page could happen.
Because I still need to do the control initialization before Page_Load to subscribe the controls to viewstate, I simply moved the initialization logic to the Page.InitComplete event so the call to Page.DataBind() could get called first.
protected void Page_Init(object sender, EventArgs e)
{
Page.InitComplete += new EventHandler(Page_InitComplete);
}
So the event tree becomes
User Control Page_Init => Hook InitComplete handler
Page (aspx) Page_Init => Bind data
User Control Page_InitComplete => Initialize the control
Couldn't you just set the property in Page_Load()?
public void Page_Load(...)
{
ctrlUser1.ValidationFormat = GetUserDateValidationFormat();
// do whatever stuff you do
}

Page unload event in asp.net

Is it possible to call a write a Page_Unload event in code behind similar to Page_Load event? I wanted to call a method on Page Unload. How do I achieve that?
With AutoEventWireup which is turned on by default on a page you can just add methods prepended with **Page_***event* and have ASP.NET connect to the events for you.
In the case of Unload the method signature is:
protected void Page_Unload(object sender, EventArgs e)
For details see the MSDN article.
Refer to the ASP.NET page lifecycle to help find the right event to override. It really depends what you want to do. But yes, there is an unload event.
protected override void OnUnload(EventArgs e)
{
base.OnUnload(e);
// your code
}
But just remember (from the above link): During the unload stage, the page and its controls have been rendered, so you cannot make further changes to the response stream. If you attempt to call a method such as the Response.Write method, the page will throw an exception.
There is an event Page.Unload. At that moment page is already rendered in HTML and HTML can't be modified. Still, all page objects are available.

Resources