Uncategorized

If an EventHandler is called twice…

…take a close look at your code 😊.

This comes from a case I worked on in the last couple of days: a customer reported a problem in one of his ASP.NET 2.0 pages, which is meant to perform some sort “long running” operation on the server. What puzzled me a bit (well… quite a bit, at the beginning) is the fact that after the user clicked posted the page (clicking on a submit button) and the long operation begun on the server, after about 90 seconds they noticed a new click button for the submit event was fired, thus restarting the whole “long” operation (and of course leading of all sort of problems this implies for the application’s logic).

Doing some tests we found that more that the above, even if he closed the browser on the client immediately after submitting the form, after about 90 seconds they still got a second click event firing for the submit button! 😲 Of course if the browser is closed on the client, it’s hard to believe that the new click and subsequent post is coming from the user… 😏

We looked and the page source produced by the server, here is an interesting excerpt:

<input type="button" name="ctl00$ContentPlaceHolder$ButtonSubmit" value="Submit data"
    onclick="this.disabled=true; this.value='Please wait...';
    __doPostBack('ctl00$ContentPlaceHolder$ButtonSubmit','');
    __doPostBack('ctl00$ContentPlaceHolder$ButtonSubmit','')"
    id="ctl00_ContentPlaceHolder_ButtonSubmit"
/>

(note that I broke the onclick Javascript line value only for formatting purposes in this post, that was on a single line)

It is clear that ASP.NET generate that button with wrong content for the onclick event handler, note the duplicated “__doPostBack(…) call”. Question is: why?

The customer sent me the click event handler method and the button declaration, which looked like the following:

<asp:Button ID="ButtonSubmit" runat="server" CausesValidation="False"
    Text="Submit data" OnClick="ButtonSubmit_Click"
    UseSubmitBehavior="false"
/>

(they also had AutoEventWireup=”true” in their @Page directive, and this is what actually put us on the right track even if not directly involved in this problem)

The customer then reviewed more closely some of their code (unfortunately he inherited this project and did not worked directly on the code, so he didn’t know all the details…), and found that in the Page_Load handler they dynamically added a Javascript call to __DoPostBack(…) using code similar to the following:

ButtonSubmit.OnClientClick = ButtonSubmit.Page.ClientScript.GetPostBackEventReference(ButtonSubmit, null);

So, now is clear that the problem was cause by both ASP.NET adding the callback handler because of UseSubmitBehavior=”false” in the button declaration, and the GetPostBackEventReference(…) call in the Page_Load method; the customer was therefore able to fix the problem simply changing the button declaration to use UseSubmitBehavior=”true” (which, by the way, is the default, read the MSDN reference for further details.

Cheers

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.