Thursday, 14 February 2008

ASP.NET double-postback bug strikes again!

A bug in ASP.NET has returned from the dead to haunt me today. I sat with one of my colleagues for over an hour to try and work out the issue to no avail. The problem was that the first Save worked fine - but I kept getting Optimistic Concurrency data errors when I saved the record for the second time (never the first). The big problem with ASP.NET bugs is that you tend to look in your code for the problem - that single attribute that shouldn't be there, the new code in our custom ObjectContainer data source or translation layer, that line of code that nullifies the value, that AJAX control not set up correctly. But there was none. After stepping through the code line by line, removing any Telerik Ajax Managers and Postback Panels -and anything remotely suspicious at - the problem was still there. After a bit more Divide and Konquering (DK for short) with CTL+E, CTL+C (the VS Shortcut for commenting out code), I finally found my old nemesis of the single empty image tag (which still exists in ASP.NET 3.5).

THE BUG:
An example of this bug is detailed here:
http://www.velocityreviews.com/forums/t119525-repost-gridview-imagebutton-causes-double-postback.html

It is also detailed here:
http://www.dotnetspider.com/qa/Question8706.aspx

The issue occurs if you have any image tags rendered by your controls which have an empty source. As soon as the browser hits that <img src=""/> tag it does a refresh of the page. The main problem with this double postback is that the second run is NOT a postback - the Page.IsPostBack property is false - but I still have all my viewstate values. This issue is incredibly frustrating as the natural inclination is to look at controls causing partial postbacks - but you'd be looking in the wrong place. I had this issue in IE 6,7 and Firefox 2.

When I have some spare time, I'll look into how the problem occurs with Lutz Roeder's handy Reflector and find out who to tell to fix this reocurring issue :o)

THE FIX:
To stop the double post-backs, just make sure all your ASP.NET controls (Image Buttons, Image Columns in grids, normal Images), all have a src attribute filled in - or otherwise, make them invisible. Otherwise, you will have phantom postbacks coming to haunt you when you least need it!

33 comments:

Mauricio said...

You saved my life!!!
Thank you very much from Argentina!!

Mike said...

Saved my life also.

Wahoo! said...

You know, I am having a similar problem. I have a gridview on my page and it contains a CommandField, which I have heard is one source of the problem. But I don't have any image controls at all. And the problem affects even postbacks that do not originate from the gridview. I have a button for inserting a new record and its click event fires twice as well.

What's really weird is that I have a C# version of this page that has none of these problems. But when I ported it over to VB for a friend, I start getting all this double postback weirdness.

the crazy cow said...

It's not a double post back.
img src=""/ does a request to "" that by default is a request to your default page...

Boyke Newalsing said...

I also still live, because of this blog article. Thanks!

ihavethepower said...

Thanks buddy this was killing me.

Rodrigo said...

Thanks a lot for your solution!

Anonymous said...

Thank you, saved my ass.

Jörg Hinrichs said...

Although i had to find out myself what was causing it, i still appreciate this article to be assured i am not crazy.

I had a slight variation of this bug, it occured by setting the "background" attribute of a "td" to a color code instead of a URL (the correct way to do this is using the "bgcolor" attribute). Leads to the exact same behaviour you described, obviously for the same reason, as "something" (the browser?) tries to interprete the color code as a URL and fails.

Anonymous said...

Thanks, you saved our head too.

Anonymous said...

Hi I found few good tutorails on this blog.

you can see them if you like

http://aspnetcsharp4.blogspot.com/2009/05/first-look-vs2010.html
http://aspnetcsharp4.blogspot.com/2009/05/c40-new-features-list.html
http://aspnetcsharp4.blogspot.com/2009/05/variance-in-c-40.html
http://aspnetcsharp4.blogspot.com/2009/05/whats-new-in-aspnet-40.html
http://aspnetcsharp4.blogspot.com/2009/05/aspnet-40-core-services.html
http://aspnetcsharp4.blogspot.com/2009/05/auto-start-web-applications.html
http://aspnetcsharp4.blogspot.com/2009/05/ajax-and-new-template-engine-in.html
http://aspnetcsharp4.blogspot.com/2009/05/shrinking-session-state.html
http://aspnetcsharp4.blogspot.com/2009/05/routing-of-urls-capability-is-added.html

http://aspnetcsharp4.blogspot.com/2009/06/access-twitter-api-using-c.html
http://aspnetcsharp4.blogspot.com/2009/06/free-aspnet40-hosting-available.html
http://aspnetcsharp4.blogspot.com/2009/06/lazy-evaluation-feature-in-c.html
http://aspnetcsharp4.blogspot.com/2009/06/difference-between-shadowing-and.html

http://aspnetcsharp4.blogspot.com/2009/07/microsoft-aspnet-40-data-access.html
http://aspnetcsharp4.blogspot.com/2009/07/microsoft-aspnet-40-whats-next.html
http://aspnetcsharp4.blogspot.com/2009/07/ajax-client-side-templating-in-aspnet.html
http://aspnetcsharp4.blogspot.com/2009/07/jquery-in-aspnet.html
http://aspnetcsharp4.blogspot.com/2009/07/c-interview-questions.html
http://aspnetcsharp4.blogspot.com/2009/07/using-ajax-control-toolbox-with-jquery.html
http://aspnetcsharp4.blogspot.com/2009/07/microsoft-interview-questions.html
http://aspnetcsharp4.blogspot.com/2009/07/json-and-aspnet.html
http://aspnetcsharp4.blogspot.com/2009/07/aspnet-questions-with-detailed-answers.html

Thanks

Anonymous said...

Good find! Thanks.

Brent said...

THANK YOU SO MUCH! I was trying to figure this out for hours, ended up doing much of what you did to try and find the source commenting out code etc, neither would have thought of an empty image source attr, anyway saved my life. Cheers Mate.

Jason said...

Related to this, but different is if you are trying to disable a button in an Ajax panel using Javascript. It causes a double postback in Firefox. I found a great free tool to fix it, and am sharing because I looked everywhere for a fix including this thread many times.

http://encosia.com/downloads/postback-ritalin/

Martin said...

BIG thank to you, David!
And thank to "the crazy cow" in comments above for deeper explanation.
4 wasted days of 2 people. What address at Microsoft I can send an invoice?

amarjit said...

Big Big and Very Big thanks... David..

You saved my life.....


i was in hell with this bug...

looking around for last two days...

Mozilla has removed this bug in 3.5.5 version

amarjit said...

I will follow the comments..

cheers

guesto! said...

wow.. width Ajax Toolkit i've only 3 postback events.. eh eh eh eh !!

I can't solve my problem...

On grid rowCommand 3 postback...
and 2 postback on the page...!!!!

umpf...

kroot said...

I had this occur in IE8, where the second IsPostback was always false.

I solved it by changing:
[td background="#f0f0f0"]
To
[td style="background-color: #f0f0f0"]

(Angle brackets replaced to get past the HTML filters)

Greenmech said...

I'm so stupid I doesn't realize it where I have to put in the src- info?? I tried to put in with Attributes but doesn't work. Also tried it with a skinfile - still not able.

Where should I put in the src-Attribut??? Code:



(using ASP.NET 2.0, VB.NET)

Greenmech said...

[asp:ImageButton ID="btn_OO_EMail" ImageUrl="~/email.gif" runat="server" Style="z-index: 100; left: 895px;
position: absolute; top: 460px" Width="32px" Height="32px" ToolTip="Schicken Sie eine E-Mail mit der eingegebenen Bemerkung."]

Richard Hauer said...

Champion.

Actually my issue was just with a regular image, not even a server-side one.

I suppose the browser is just trying to load an image and by not giving it a src it's just doing the next best thing.

Good in theory, not so much in practice.

Muhammad Azeem said...

This is a nice article..
Its very easy to understand ..
And this article is using to learn something about it..

c#, dot.net, php tutorial

Thanks a lot..!

mthakershi said...

I have one ImageField in my GridView. I removed it. But still debugger stops at objDSTabResults_Selected twice with IsPostBack set to false on page load. Meaning post back is happening twice. I am using IE8. What am I missing?

Ed said...

Well I didn't know that. Thanks.


Ed
http://bookingac.com/

teste said...

wow! i had the same issue now, but i tried visible="false" (no src no nothing to render)before read this post ;D!

it is pointless display have a image with empty src =p!

nice post!

saitodisse said...

Saved my life also.

Not Name said...

I have a similar problem, not an elegant solution is to declare a local integer variable page, if Integer = 0 is first postback Also Integer = 1
may be a solution

sergio said...

grazie mille... ho avuto anche io lo stesso problema. L'unca differenza è che a me dava il problema con dei tag div a cui avevo messo l'attributo runat="server".

sergio said...

Sorry I posted in Italian. I had a same problem but I found a problem with tag div with runat="server" attribute. I solved a problem deleting the atttribute.

Rohit Bisariya said...

Thanks dear... U saved my so much time.

lingmaaki said...

More about......Asp.Net Postback

Ling

Umesh Patil said...

You saved my life and time too!!!!!!!!!!!!!!!!!!!!!