I have 2 aspx pages. Both of them use the same MasterPage and both of them inherit from the same base class 'BasePage' which is of type System.Web.UI.Page. I overrode the SqlPagePersister property on the BasePage. For 1 page this works fine, for the other it doesn't. The sequence of events im seeing is this:
Page A:
MasterPage Init
Page Load
Retrieval of SqlPagePersister Property
Page B:
Retrieval of SqlPagePersister Property
MasterPage Init
Page Load
Why would 2 pages with an identical set up call these methods out of order and what can be done to fix this?
The sequence of events for Page B can't happen in the life cycle of an ASP.Net page. The master page init and page load must be in a state of being "re-fired". You may want to look at any previous page action that is being shunted into Page B because the init/load must happen before the retrieval can even begin.
There must be some action happening before Page B property retrieval, but that doesn't mean you're going to catch it necessarily in your debug with your normal casual breakpoints. You may have to get creative and start at the PreInit of your base class.
Related
I have read this page: Viewstate n page lifecycle and also ASP.NET page lifecycle . My questions are these:
1 - Instantiaton means that the code for the control hierarchy is CREATED, and then in Initialization stage, it's executed, right?
2 - Does the Instantiation stage which is described in the page lifecycle, occur everytime? That is, does this occur for the first time and also during postbacks??
Yes, the control hierarchy is rebuilt every single time the page loads (including postbacks).
On Postback, The controls are hydrated with values from the ViewState.
PreInit The entry point of the page life cycle is the pre-initialization phase called “PreInit”. This is the only event where programmatic access to master pages and themes is allowed. You can dynamically set the values of master pages and themes in this event. You can also dynamically create controls in this event.
But this definition is valid for other events like load init etc. Correct?
I meant, this job can be done in other events as well.
Query What's the unique meaning of PreInit ?
Sometimes there can be overlaps depending on what you're doing, but it's good practice to stick with the actual ASP.NET page life cycle and use the correct events. There is a good breakdown on MSDN of each event's actions.
Init for example is raised after the controls have been created, so any dynamic changes won't take effect immediately.
In object-oriented languages, if class A contains class B as a member, you can access class B's properties from class A's constructor (after you instantiate class B first).
However in ASP.Net, my understanding is that a Page object contains server control objects as its members, but I do not understand why, if you try to access a server control's properties from the Page constructor, you get a NullReferenceException.
It sounds more like a Life Cycle problem. The controls contained on your page is not created at the same time as your Page object, but later in the cycle of your httprequest.
This page gives a clear picture of the cycle: http://msdn.microsoft.com/en-us/library/ms178472.aspx.
You should instead override the Init-method to be sure your controls are initialized. Quote from the article
Raised after all controls have been initialized and any skin settings have been applied. The Init event of individual controls occurs before the Init event of the page.
Use this event to read or initialize control properties.
In the constructor, the ASPX has not run yet, so all of the server-side controls are null.
Move your code to Page_Load.
I have a simple setup with the master page housing some controls used by all child pages.
I found when moving to new pages the master page page loads event fires as a non post back and read the solution was to store it's current values somewhere for retrieval. Ok all done.
The child page uses these values to run a report. When I switch to a new report, all is well. If I change the values in the master page the master page and the sub page load events fire.
The load event for the sub page fires first, picks up the values from the master page which are still the old values and then finally the master page events fire and all the new values are stored. The report hasn't changed as it still ran from the old values.
I can't really see a way around this. All you ever hear is that master pages are a saving grace but I swear i've never jumped through so many hoops to get a page to load correctly.
And now this!
Anyone see a plan to resolve it?
Populating the controls during the Masterpage's Init will solve your issue from the sounds of it.
http://msdn.microsoft.com/en-us/library/dct97kc3.aspx
An alternate approach would be to have a public sub in the content page(s) that you can call from the masterpage during load which in effect acts as an alternate to the page load event.
A slightly more indepth look at the page lifecycle when using masterpages:
http://weblogs.asp.net/ricardoperes/archive/2009/03/08/asp-net-page-events-lifecycle.aspx
a) Am I right in assuming that only after controls on Master page are merged into the control tree for the Page, can controls ( both those in Master page and in a content Page ) be initialized with their declarative values ( values set during design time )?
b) If my above assumption is correct, then these controls cannot be initialized with their design-time values during Page.PreInit, since during Page.PreInit event stage we’re still able to dynamically set a Master page?! So if that is the case, when are controls initialized with their declarative values? During Init event or…?
thanx
Pages are compiled into .Net classes, so the parsing of the markup actually happens outside of the page lifecycle. By the time a request reaches your Page, the page class has been compiled from the combination of the markup and codebehind.
This is easily verified by just putting a Page_PreInit handler and looking at the properties of a control on the page. You'll see that they are set.
The MasterPage/Page relationship is just a function of how the HTML will get rendered, and the naming containers that everything lives in.
When the actual Page compilation happens is partially a function of how you've set up your project, and partially a function of ASP.Net's monitoring of the files in the application.