ASP.NET AJAX weirdness - asp.net

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.

Related

UpdatePanel Conditional updatemode not working

I found this thread while trying to resolve my issue unfortunately this I can't seem to figure out the problem since I already have everything the way it should be.
I've got 3 updatepanels that each call a function on a .js file setup like this:
<asp:UpdatePanel ID="upPnlGeneralinfo" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<script type="text/javascript">
Sys.Application.add_load(BindPageLoad);
</script>
Each have a different ID of course. Whenever a control calls a postback within the update panel it works, however in the js file I added a console.log("running the js file") and I can see that it's being called three times meaning it's all three updatepanels are being refreshed instead of just the one.
All the triggers are inside each of the respective updatepanels so I shouldn't need to add any triggers (I did just to make sure and it makes no difference). Shouldn't the UpdateMode=Conditional resolve this?
Also worthy to mention, none of my code behind ever calls any updatepanel.update(). I tried adding that for each control to their respective panels and that also made no difference.
Any ideas?
It doesn't necessarily mean all your update panels are being refreshed.
The MSDN docs say the client load events are raised after either a synchronous (full page postback) or asynchronous (partial page) postback.
This might mean that only one of your update panels is refreshing as intended, but all three event handlers are run again after the async postback because of how they were hooked up using MS Ajax.
MSDN excerpt:
Client Events of the Application and PageRequestManager Classes
Sys.Application.load Event
Sys.Application.add_load(handler);
Raised after all scripts have been
loaded and all objects in the
application that are created by using
$create are initialized. The load
event is raised for all postbacks to
the server, which includes
asynchronous postbacks.
-- http://msdn.microsoft.com/en-us/library/bb386417.aspx
Working with Partial-Page Rendering Events states a different event that runs only when the entire page loads:
During ordinary page processing in the
browser, the window.onload DOM event
is raised when the page first loads
-- http://msdn.microsoft.com/en-us/library/bb398976.aspx
This the regular DOM load method, not part of MS Ajax.
Therefore I assume if you hook your client code to the regular window.onload event then it will run only when the full page loads, on the first time, not on successive async postbacks (aka update panel/partial refresh).
Whether or not this knowledge is harnessable to provide the outcome you want I'm unsure. Maybe you're looking at only the MS Ajax objects for a solution when a hybrid browser/MS Ajax client solution exists.

What happens between Page.PreLoad and Page.Load events?

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.

What can prevent a Postback in ASP.NET?

We have a user who is having problems with a ASP.NET app. The user hasn't been available to gather many details, but at this point our best guess is that the PostBack is not occurring. Something is going wrong between when the user clicks the LinkButton and when the HTTP Request is supposed to be made.
(User does have JS enabled)
Beyond solving the immediate problem, it might be helpful for posterity to assemble the canonical list of things that can break PostBack behavior of ASP.NET controls.
If you have say a button that has a postback event as well as a javascript event on click, if the javascript event that is fired returns false postback will be stopped.
I would first check that your <form> tags are well formed and that you don't have nested <form> tags. Both times I've debugged something to do with postback this turned out to be the problem. It's confusing because it's a browser dependent issue.
Having a self-closing <script /> tag can stop postbacks occurring. Get the user to send you any javascript errors from their log. There is actually a decent JS debugger in IE8 (about the only good thing in it!).
a form with no method attribute, or method note being set to POST
an onsubmit event handler that does not return true
trying to submit the form programatically, but unable to locate the form by id as there is another element with the same id on the page

ASP.net viewstate changes validation and jQquery AJAX

Ok, so the problem is as follows: I'm using jQuery's AJAX in order to make behind the scene calls within the page (on events such as voting an item) and changing the content in the appropriate element. The problem occurs when I mix AJAX with ASP.net's AJAX, more precisely when I try to do a postback AFTER I've used jQuery on the page to perform an action. The page's viewstate is changed and validation fails (which would seem somewhat normal as a matter of fact).
My question is: can I disable the validation somehow so that I can perform postbacks combined with the chaged page viewstate? So far searching on how to disable it yielded no results.
A more practical example is on a comments page where I allow voting the comments and posting new comments as well. So should a user vote a comment and THEN post his own, the page's contents is changed, and thus validation fails. Also, I've tried placing the comment form within an update panel as to prevent the entire page from posting, but it still fails.
Of course I could use an alternate route and have a different page for handling the event and just call that via jQuery's AJAX, but I was wondering if I could do this by combining ASP.net and jQuery.
Thanks in advance.
If you want to disable viewstate verification, you can set it at the page or config level by using Page.EnableViewStateMac = false.
http://msdn.microsoft.com/en-us/library/system.web.ui.page.enableviewstatemac.aspx
It's not necessarily a good idea though because the validation functionality is there to protect from viewstate tampering, which you'll be turning off...
If you're running into issues with invalid viewstate because of jQuery ajax calls, one option is to consider using the Ajax controls, such as the UpdatePanel. You can wrap certain controls and mark the UpdatePanel as conditional to ensure a small round trip. This will not interfere with viewstate and allow you to continue to use viewstate validation and ajax at the same time.
There may be ways to use jQuery ajax calls and not interfere with viewstate validation. Others may be able to highlight this approach.

How do I temporarily convert an ASP.NET Ajax form to not use partial page updates?

I need the ability to temporarily turn off the partial page update behavior for an ASP.NET Ajax / UpdatePanel based page. (The reason is to circumvent the issue where IE blocks "automatic file downloads" for downloads generated as a result of this postback, but I don't want to distract from my original question)
I looked at the client side javascript libraries hoping to find a switch somewhere. I think a solution might involve using javascript to override the 'onclick' event handler for the control that acts as the trigger, and then calling "submit" on the form itself..
Also, using the EnablePartialRendering property on the server-side ScriptManager control won't work because that is done when the page is being built. I need to be able to do this as a result of switching a drop down list box.
Any ideas?
Cheers!
/ Sean
Well, after much trial and error, I found two approaches that seemed to work:
Use Javascript to manually submit the top level form associated with the page. This usually has the ID of "form1".
Create a button that is outside of any UpdatePanels and use Javascript to click the button.
I wound up using the second approach, since it allowed me to handle the event with a specific routine without the need to guess that my postback came from a Javascript call.
This is an example of the code that performed the postback:
...
if (isDownload) {
document.getElementById('FullPostbackSubmitter').click();
return;
}
...
Hope this helps someone else!
You can set the EnablePartialRendering property of your ScriptManager to false.

Resources