I am having an ASP.net page in my page i am having this as my code behind files.
on first access the page the page preinit, init, load methods are called. on postbacks
the preinit, init, load methods are called.
My question is LoadViewstate and control state events (Overridden methods) are not firing after postbacks also
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
}
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
}
protected override void LoadControlState(object savedState)
{
base.LoadControlState(savedState);
}
protected void Page_Init(object sender, EventArgs e)
{
}
protected void Page_Load(object sender, EventArgs e)
{
// lblName.Text = ViewState["Test"].ToString();
}
This method is used primarily by the
.NET Framework infrastructure and is
not intended to be used directly from
your code. However, control developers
can override this method to specify
how a custom server control restores
its view state. For more information,
see ASP.NET State Management Overview.
The LoadViewState method restores the
view-state information that was saved
during a previous SaveViewState
request. The WebControl class
overrides the base LoadViewState
method to handle the ViewState, Style,
and Attributes properties.
Also note
Control State Sometimes you need to
store control-state data in order for
a control to work properly. For
example, if you have written a custom
control that has different tabs that
show different information, in order
for that control to work as expected,
the control needs to know which tab is
selected between round trips. The
ViewState property can be used for
this purpose, but view state can be
turned off at a page level by
developers, effectively breaking your
control. To solve this, the ASP.NET
page framework exposes a feature in
ASP.NET called control state.
The ControlState property allows you
to persist property information that
is specific to a control and cannot be
turned off like the ViewState
property.
Asp.Net StateManagement link
If your control is a customer server control take a look at
iStateManager
And for the complete overview of viewstate - had to search my bookmarks try
Truly understanding viewstate
ASP.NET optimizes this call, and calls the LoadViewState only if there is any custom data written to the view state.
If you set something to the view state in the first call (e.g. ViewState["foo"] = 42;), the LoadViewState will be called in the next (and subsequent) callbacks.
Related
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.
In an effort to speed up my site, I am trying to disable the viewstate as I don't think I am using it everywhere. I have a master page setup with user controls loaded (using LoadControl) in default.aspx. My typical page setup would be:
Main.master -> Default.aspx -> ControlWrapper.ascx -> MyControl.ascx
I have put EnableViewState="false" in my Default.aspx page. Now when I try and read a value from a DropDownList in MyControl.ascx it comes back blank when the form is posted. First all, why is this? I thought I should still be able to read the value from the drop down list?
I then tried enabling the ViewState on that control and it didn't work.
I also tried enabling the viewstate on the Page_Init event of MyControl.ascx using Page.EnableViewState = True; but that didn't help either.
I guess I am misunderstanding the viewstate somewhat, can someone point me in the right direction please?
p.s I don't know if this information is relevant but I am adding the contents of the DropDownList dynamically in the Page_Load event. (Thinking about it, could this be the issues - Will test this now).
Thanks.
With viewstate turned off, the values you are loading in Page_Load are no longer in the list when you post back (until you reload them obviously). If you want to work without viewstate, you will need to set the selected item from the value in Request.Form.
protected void Page_Load(object sender, System.EventArgs e)
{
ddlItems.Items.Add(new ListItem("test1", "test1"));
ddlItems.Items.Add(new ListItem("test2", "test2"));
ddlItems.Items.Add(new ListItem("test3", "test3"));
if (Page.IsPostBack)
ddlItems.SelectedValue = Request.Form["ddlItems"];
}
When you've set ViewState to false the dropdown needs to get populated before page load - which means you probably should do it at page init. Something like this:
protected void Page_Init(object sender, System.EventArgs e)
{
ddlItems.Items.Add(new ListItem("test1", "test1"));
ddlItems.Items.Add(new ListItem("test2", "test2"));
ddlItems.Items.Add(new ListItem("test3", "test3"));
}
Then you should be able to read the value at load:
protected void Page_Load(object sender, System.EventArgs e)
{
someTextBox = ddlItems.SelectedValue;
}
A bit of background:
On this page: Microsofts page cycle
At the image with the page cycle there is the methods "ProcessPostData" and "LoadPostData" firing in between Init and Load. The post data for the drop down contains the selected value - but not the possible values, so when it loads the post data it is essential that the possible values are already there (or it won't be able to set the selected value). Also before the post data has been loaded the selected value has not been set.
If viewstate is enabled it saves and retrieves the possible values in between postbacks.
I will assume you're using .NET 4. View State is the method that the ASP.NET page framework uses to preserve page and control values between round trips.
The reason it didn't work for you when View State was turned off is because that control was rendered again when you performed a PostBack to the server, meaning you lost your selected value.
The reason it didn't work for you when View State was off for the page, but on for the control is because in order for that to work, the following conditions must be met:
The EnableViewState property for the page is set to true.
The EnableViewState property for the control is set to true.
The ViewStateMode property for the control is set to Enabled or inherits the Enabled setting.
ASP .NET View State Overview
When you did EnableViewState = false; on a page then you should not expect DropdownList.SelectedValue after postback.
It will be good if you Enable/Disable ViewState on particular controls rather than disabling whole view state by specifying it on page directive.
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.
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.)
I want to create a number of masked edit extenders from codebehind. Something like:
private MaskedEditExtender m_maskedEditExtender;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
m_maskedEditExtender = new MaskedEditExtender()
{
BehaviorID = "clientName"
};
m_maskedEditExtender.Mask = "999999999";
this.Controls.Add(m_maskedEditExtender);
}
protected override void Render(HtmlTextWriter writer)
{
m_maskedEditExtender.RenderControl(writer);
}
When I do this, I get a NullReferenceException on OnLoad of MaskedEditExtender. What is the correct way of doing that? Please note that putting the extender into a repeater-like control and using DataBind does not work for me.
Edit: I do not have an update panel. Turns out I also need to specify a target control on serverside.
See ASP.NET Page Life Cycle Overview if this is in a Page subclass. If you scroll down to the event list, that page advises you to use the PreInit event to create any dynamic controls. It's necessary to do that early to ensure that ASP.NET cleanly loads ViewState at the right stage, among other things.
If you are doing this in a web user control or custom control, though, override CreateChildControls and do this in there.
Post a more complete code example if that doesn't help.
Your example is not providing a TargetControlID.
Do you have an updatePanel on the page? I had problems dynamically creating extenders as they weren't being added to the updatePanel content.
I also think you have to do somethin with the ScriptManager (registering the extender) but I could be mistaken (I don't have access to the code I did dynamic extenders at the moment).
Provide the proper TargetControlID value to MaskedEditExtender