Question is pretty straight forward.
Is there a technical reason for the existence of Page.PreLoad or is this just convenience to have a place where you can neatly place code that always have to be executed before the Load code?
Is there a difference between adding code in the PreLoad event handler and adding code at the top of the Load event handler?
And what would be a typical scenario where you use PreLoad?
Thanks!
What happens between Page_PreLoad and Page_Load is that all the other PreLoad event handlers (not just the handler(s) you wrote) have a chance to run. There is no reason to put code in Page_PreLoad. You see, chances are that you do want to be sure all the other PreLoad event handlers have fired (I'll explain in the last paragraph). Plus, by using Page_Load instead of Page_PreLoad, you give control adapter authors a chance to override the behavior of your implementation.
The purpose of the Page.PreLoad event (as far as I can tell) is to provide a hook for control authors. The behavior of the load phase of the page lifecycle, is that the Load event is raised on the page before it is raised on all its child controls. As a control author, you might want to perform some action after viewstate is loaded (so Init is too early), but before Page_Load is called (so Load is too late). How you do that is to add an event handler to Page.PreLoad.
Some of the built-in ASP.NET data binding controls use this hook to be able to auto-magically re-DataBind themselves when you update the control in certain ways after its viewstate has been loaded. Using a flag set in Page.PreLoad, a control can distinguish between changes you make in Page_Init and changes you make in Page_Load. If you implement Page_PreLoad and you don't take care to avoid touching any control that hooks PreLoad in this way, you're going to see undefined behavior because you don't know whether PreLoad is firing on the control or on the page first. To avoid this complication, always use Page_Load instead, as there is no reason not to.
I'm sure I've answered this a few times, but you're best bet is to have a thorough read thorugh the ASP.NET Page Lifecycle Overview from Microsoft and the ASP.NET Page Lifecycle explanation from 15 Seconds.
Related
Ok, so I am working on a custom framework above the .NET framework, and some instructions are not written / called at the good places.
For example, a postback is done on the same page. Then, a Response.redirect occurs right within the page_load; but at this point, the new values of the controls of the page are not yet handled, so they get lost...
Therefore, I wanted to know whether it was possible to force the pagelife_cycle to go forward before the call to response.redirect, so that I can get the right values.
I can't just make that call in another function, because the page I am working on is called by many web applications (about 1-2k), and it would completely change their behaviour, which is not acceptable!
Is that even possible?
See a bit the second image and the Load PostBack Data section. Before the Load event of the page is raised, a textbox is already initialized. You can catch the value by overriding OnPreLoad or by adding a handler at PreLoad event.
Ok, I thought I understood these topics well, but I guess not, so hopefully someone here can clear this up.
Page.IsAsync seems to be broken. It always returns false.
But ScriptManager.IsInAsyncPostBack seems to work, sort of.
It returns true during the round trip for controls inside UpdatePanels. This is good; I can tell if it's a partial postback or a regular one.
ScriptManager.IsInAsyncPostBack returns false however for async Page Methods. Why is this? It's not a regular postback, I'm just calling a public static method on the page.
It causes a problem because I also realized that if you have a control with AutoPostBack = false, it won't trigger a postback on it's own, but if it has an event handler on the page, that event handler code WILL run on the next postback, regardless of how the postback occurred, IF the value has changed.
i.e. if I tweak a dropdown and then hit a button, that dropdown's handler code will fire. This is ok, except that it will also happen during Page Method calls, and I have no way to know the difference.
Any thoughts?
As Tjaart points out, Page.IsAsync has nothing to do with AJAX! See MSDN for a bit more info about IsAsync and see http://msdn.microsoft.com/en-us/magazine/cc163725.aspx for a fuller description of async pages].
Page methods are web services by a different name. The ScriptManager will emit the necessary JS boiler plate to make creating an XHR that invokes the web service very easy but that's all ScriptManager has to do with them really.
As the MSDN page states, ScriptManager.IsInAsyncPostBack will only be true if the request is in "partial rendering mode" so ScriptManager.IsInAsyncPostBack will be false when you are executing a page method because that request has not been spawned as a result of a partial postback (i.e. an UpdatePanel refreshing its contents).
Now it sounds like you are getting server side event handlers being executed as an apparent result of calling a page method from JS. AFAIAA, invoking a page method using javascript should not cause the page to go through its normal page lifecycle - so Page load, init etc. and these events should not be executing. So that is strange.
Suggestion: -
See Anz's comments and Dave's replies here encosia.
Could it be that you are having similar problems to Anz? i.e. The page method is invoked and but then your page is posting back immediatly after?
This is so because ASP.NET Ajax and ASP.NET Callbacks are two different things and are implemented differently. Unfortunately you have to use both Page.IsAsync and ScriptManager.IsInAsyncPostBack.
Page.IsASync probably returns whether the page was set as Async in the page directive
<%# Page Language="vb" Async="true" ...
The autopostback flag is so that you don't get a postback after every single control action, so the user can fill in an entire form and then only create the postback and trigger all the related code.
It's not really weirdness, they designed it this way so that the server side code will always be synchronized with the client side. So if you make a drop down list selection on the page and a postback occurs then that drop down list change executes it's own code along with the control that triggered the postback. You may want to read up more on the ASP .Net page lifecycle. it made things much more clear for me.
I am adding controls dynamically in my webpage.
I add them in onload method.
everything is working fine..
But I m a bit confused about how it works..
I have read in so many articles that all controls get their values from viewstate before load event. Then how my dynamically added controls get their values when i am adding them in OnLoad event ie after LoadPostData event.
Load them in Page_Init()
Review the page lifecycle for more info:
http://msdn.microsoft.com/en-us/library/ms178472.aspx
This is a helpful article as well:
http://www.code-magazine.com/article.aspx?quickid=0305101&page=2
In a typical GET request, the controls are created at Page_Init. Since these dynamic controls are not part of page markup, so in POST BACK, you need to recreate. Be sure that when recreating, it must have same ID otherwise your events/values will not preserve.
Dynamically added controls play catch up in the control lifecycle. Even if you add a control after it has missed the LoadViewState event, that event will still occur for the control at the time when the control is added to the page. I would suggest that any poor souls who have not had the privilege of reading this article, do so immediately:
http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx
Source:
Professional programmer, I do not claim to be an expert, but I have read tons of articles about ViewState. :)
In the ASP.NET Page LifeCycle there is the Page.LoadComplete event.
The MSDN documentation says 'Use this event for tasks that require that all other controls on the page be loaded'. What exactly might this be? What would a 'best practice' say that LoadComplete should be used for?
When you hook up several methods to the Load event you don't know the order they will get called. So you have the PreLoad, Load and LoadComplete events to have some more control as to in what order your code gets called.
The use of this might not always be clear when working only with your page class. When working with controls however, with the need to have some code running at Load time, you might want to make it run right before or right after what would normally happen in the Load event. Then you can use the PreLoad and LoadComplete methods.
As simon mentioned, the same pattern is followed with the Init event...
More information can be found in this MSDN article about the ASP.NET Page Lifecycle
EDIT: It seems, from the MSDN article that LoadComplete is called AFTER your control events like Button.Click have been raised.
Say you have multiple controls that prepare some data in the load event. If you want to take action on that data in the load step of the ASP.NET lifecycle you need to have a way to execute after all the other load's have run. Hence the "load complete". There's also an "init complete".
Here is one example where I was trying to use Page_Load and someone correctly pointed out that LoadComplete would be better.
I have a problem with maintaining state in an ASP.NET AJAX page. Short version: I need some way to update the page ViewState after an async callback has been made, to reflect any state changes the server made during the async call.
This seems to be a common problem, but I will describe my scenario to help explain:
I have a grid-like control which has some JavaScript enhancements - namely, the ability to drag and drop columns and rows. When a column or row is dropped into a new position, an AJAX method is invoked to notify the control server-side and fire a corresponding server-side event ("OnColumnMoved" or "OnRowMoved").
ASP.NET AJAX calls, by default, send the entire page as the request. That way the page goes through a complete lifecycle, viewstate is persisted and the state of the control is restored before the RaiseCallbackEvent method is invoked.
However, since the AJAX call does not update the page, the ViewState reflects the original state of the control, even after the column or row has been moved. So the second time a client-side action occurs, the AJAX request goes to the server and the page & control are built back up again to reflect the first state of the control, not the state after the first column or row was moved.
This problem extends to many implications. For example if we have a client-side/AJAX action to add a new item to the grid, and then a row is dragged, the grid is built server-side with one less item than on the client-side.
And finally & most seriously for my specific example, the actual data source object we are acting upon is stored in the page ViewState. That was a design decision to allow keeping a stateful copy of the manipulated data which can either be committed to DB after many manipulations or discarded if the user backs out. That is very difficult to change.
So, again, I need a way for the page ViewState to be updated on callback after the AJAX method is fired.
If you're already shuffling the ViewState around anyway, you might as well use an UpdatePanel. Its partial postbacks will update the page's ViewState automatically.
Check out this blog post: Tweaking the ICallbackEventHandler and Viewstate. The author seems to be addressing the very situation that you are experiencing:
So when using ICallbackEventHandler you have two obstacles to overcome to have updated state management for callbacks. First is the problem of the read-only viewstate. The other is actually registering the changes the user has made to the page before triggering the callback.
See the blog post for his suggestions on how to solve this. Also check out this forum post which discusses the same problem as well.
I actually found both of those links you provided, but as noted they are simply describing the problem, not solving it. The author of the blog post suggests a workaround by using a different ViewState provider, but unfortunately that isn't a possibility in this case...I really need to leave the particulars of the ViewState alone and just hook on to what is being done out-of-the-box.
I found a fairly elegant solution with Telerik's RadAjaxManager. It works quite nicely. Essentially you register each control which might invoke a postback, and then register each control which should be re-drawn after that postback is performed asynchronously. The RadAjaxManager will update the DOM after the async postback and rewrite the ViewState and all affected controls. After taking a peek in Reflector, it looks a little kludgy under the hood, but it suits my purposes.
I don't understand why you would use a custom control for that, when the built-in ASP.NET AJAX UpdatePanel does the same thing.
It just adds more complexity, gives you less support, and makes it more difficult for others to work on your app.