How to prevent multiple clicks of a submit button in ASP.NET
Many of the bugs reported against ASP.NET applications have to do with unexpected user input. One common instance of this is when a user clicks a button, but does not wait until the postback is completed, and clicks it again... and again... and again... messing with your business logic, and stressing your server. This article will show you, with one line of code, how to protect your code against this stupid user trick.
The Solution
In your Page_Load function, inject some client side code by adding an onlclick attribute to your button control. My example below does three things, it changes the text of the button, disables it, then causes a postback to fire. The reason for the last step, is that once you disable the button, you can no longer submit the form in the normal way. I've used the GetPostBackEventReference method to ensure that the __doPostBack client side function is included on the page.
private void Page_Load(object sender, System.EventArgs e)
{
this.Button1.Attributes.Add("onclick",
"this.value='Please wait...';this.disabled = true;"
+ this.GetPostBackEventReference(this.Button1));
}
To test this code, I added a Click event handler for my button. To visually see the disabled appearance and changed text, I caused the method to block for 2 seconds using Thread.Sleep.
private void Button1_Click(object sender, System.EventArgs e)
{
System.Threading.Thread.Sleep(2000);
this.Label1.Text = DateTime.Now.ToString();
}
Conclusion
One line of code is all you need to prevent this particular stupid user trick. May all your coding be bug free.
UPDATE
Several good comments below prompted me to update my code. I also split the code up into several lines for easier reading. It should now work whether you have validators on the page or not.
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("if (typeof(Page_ClientValidate) == 'function') { ");
sb.Append("if (Page_ClientValidate() == false) { return false; }} ");
sb.Append("this.value = 'Please wait...';");
sb.Append("this.disabled = true;");
sb.Append(this.Page.GetPostBackEventReference(this.Button1));
sb.Append(";");
this.Button1.Attributes.Add("onclick", sb.ToString());
I have written this as a control that you can just drop on your page. Check it out here.
posted on Tuesday, October 21, 2003 1:22 PM
Feedback
# re: How to prevent multiple clicks of a submit button in ASP.NET 10/25/2003 3:29 PM saji
Good way of handling
# re: How to prevent multiple clicks of a submit button in ASP.NET 10/28/2003 7:45 PM alaalam
will it affect the behavior of the validator controls in the web form?
# re: How to prevent multiple clicks of a submit button in ASP.NET 10/28/2003 7:48 PM alaalam
i've noticed that validation is bypassed whenever i add something to onlick attribute
# re: How to prevent multiple clicks of a submit button in ASP.NET 10/29/2003 6:47 AM John
Does it bypass just client side validation? Or both client and server validation?
# re: How to prevent multiple clicks of a submit button in ASP.NET 10/30/2003 1:33 PM Garry Lowther
This works great if you have no page validators...
This view source code is the button on a page with no validators:
<input type="submit" name="btnEdit" value="Edit Vacancy" id="btnEdit" title="Edit current vacancy" onclick="this.value='Please wait...';this.disabled = true;__doPostBack('btnEdit','')" style="height:29px;width:141px;" />
Here is another button with page validators on the form:
<input type="submit" name="btnUpdate" value="Update Vacancy" onclick="this.value='Please wait...';this.disabled = true;__doPostBack('btnUpdate','')if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate(); " language="javascript" id="btnUpdate" title="Update the vacancy details" style="height:29px;width:141px;" />
As you can see, a lot more code, which in my page, renders the code ineffective on pages with validators.
Any ideas?
# re: How to prevent multiple clicks of a submit button in ASP.NET 10/30/2003 5:08 PM John
Ok, when you have validators, you can change your code in the Page_Load event as follows:
this.Button1.Attributes.Add("onclick","if (typeof(Page_ClientValidate) == 'function') {if (Page_ClientValidate()) {this.value='Please wait...';this.disabled = true;this.GetPostBackEventReference(this.Button1) + ";}}");
# re: How to prevent multiple clicks of a submit button in ASP.NET 10/31/2003 5:21 AM Garry Lowther
Many thanks John - that works great.
I re-wrote my VB.Net code to accomodate your changes. This is the function in GlobalModule.vb which is public for all web forms:
Public Sub ButtonClickEventGovenor(ByVal btn As System.Web.UI.WebControls.Button, ByVal PageHasValidators As Boolean)
Dim sJavaScript As String
If PageHasValidators Then
sJavaScript = "if (typeof(Page_ClientValidate) == 'function') {if (Page_ClientValidate())" & _
"{this.value='Please wait...';this.disabled = true;" & _
btn.Page.GetPostBackEventReference(btn) & ";}}"
Else
sJavaScript = "this.value='Please wait...';this.disabled = true;" & _
btn.Page.GetPostBackEventReference(btn)
End If
btn.Attributes.Add("onclick", sJavaScript)
End Sub
This is how I call the code from a web form with no validators:
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
...
Call ButtonClickEventGovenor(btnEdit, PageHasValidators:=False)
...
And this is the call from a web form with validators:
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
...
Call ButtonClickEventGovenor(btnUpdate, PageHasValidators:=True)
Call ButtonClickEventGovenor(btnApplications, PageHasValidators:=True)
...
# re: How to prevent multiple clicks of a submit button in ASP.NET 11/4/2003 1:42 AM Simon
Hi Garry, I tried your VB script .. it looks cool!, but I get a jscript run time error every time I hit the button, VS highlights the section in the client script starting at "_dopostback('btnPublishNow','')" saying "object expected"
The client side script is:
<input type="submit" name="btnPublishNow" value="Yes publish now" id="btnPublishNow" onclick="this.value='Please wait...';this.disabled = true;__doPostBack('btnPublishNow','')" style="height:32px;width:160px;" />
Any ideas?
cheers simon
# re: How to prevent multiple clicks of a submit button in ASP.NET 11/4/2003 6:07 PM andy
Thanks for all the info. A few more notes on image buttons.
1) If you don't set CauseVaidation to false, the onclick attribute will be the second with the same name and the code you add will be ignored.
2) With an image button, I don't change the text but the image source:
ImageButton_Update.Attributes.Add("onclick",
"if (typeof(Page_ClientValidate) == 'function') {if (Page_ClientValidate()) {this.src='btnProcessing.gif';this.disabled = true;" + this.GetPostBackEventReference (this.ImageButton_Update) + ";}}");
Thanks for the help
# re: How to prevent multiple clicks of a submit button in ASP.NET 11/25/2003 12:30 PM Adam
I have added the code that Garry Lowther (thanks!) designed. This works great for pages without RequiredFieldValidators. However, i cannot get it to disable the button or change the text for pages that have RequiredFieldValidators. Is settings i need to change or any light somebody can shine on this issue?
# re: How to prevent multiple clicks of a submit button in ASP.NET 12/1/2003 7:48 AM ZiZou
Thank you very much for this tip.
It works really great with only one line of code, even with validators (required, expression and/or others).
The only thing not to forget is to set the CausesValidation property of the Button or the ImageButton to false in order to avoid the automatically client code to append our code.
This tip is the ultimate solution, light and efficient.
I use it with ImageButtons and maybe you have a tip to load the "alternate" image before displaying it ? In my case, when the user click, the src change but the new image is not displayed (red cross instead), I think the image has not enough time to be loaded.
If you have another tip for that I would be a second time very grateful to you ;)
# re: How to prevent multiple clicks of a submit button in ASP.NET 12/2/2003 7:40 AM ZiZou
I've finally found how to do that. It may be useful for you so I paste the code :
myImageButton.Attributes.Add("onclick", "if (typeof(Page_ClientValidate) == 'function') {if (Page_ClientValidate()) { this.src = 'image2.jpg'; this.disabled=true; setTimeout('" & Replace(GetPostBackEventReference(myImageButton), "'", "\'") & ";', 2000);}}").
In this example, it waits 2 seconds before doing the necessary postback : the second image has enough time to be loaded and displayed.
# re: How to prevent multiple clicks of a submit button in ASP.NET 12/3/2003 1:38 PM Kumar
how can this be done in vb.net....
private void Page_Load(object sender, System.EventArgs e) { this.Button1.Attributes.Add("onclick", "this.value='Please wait...';this.disabled = true;" + this.GetPostBackEventReference(this.Button1)); }
# re: How to prevent multiple clicks of a submit button in ASP.NET 12/12/2003 2:22 PM rocky
just implement one of the above techniques and go home and relax
# re: How to prevent multiple clicks of a submit button in ASP.NET 12/15/2003 5:50 AM cseppala
Thank you very much - you saved me much agony!
# OneClickButton 1/6/2004 11:58 AM aspZone.com
# re: How to prevent multiple clicks of a submit button in ASP.NET 1/7/2004 7:53 AM Pancho
Anyone knows if it´s portable to ASP (not .NET)?
# re: How to prevent multiple clicks of a submit button in ASP.NET 1/7/2004 8:05 AM John
Pancho, if you want this functionality in classic ASP, all you would have to do is add the onclick argument to the html tag. Much easier actually. ASP.NET makes it harder because the onclick would get evaluated serverside.
# Prevent Multiple clicks in submit 1/14/2004 1:32 PM Braulio Graca Patricio
# re: How to prevent multiple clicks of a submit button in ASP.NET 2/5/2004 8:54 AM troy
John and Garry - your code worked awesome!
-Troy
# re: How to prevent multiple clicks of a submit button in ASP.NET 2/17/2004 2:51 AM Amirouche
Really nice code, you saved my life!!!
Don't forget the "CauseVaidation to false" in your aspx buttons like andy said!! ;)
# re: How to prevent multiple clicks of a submit button in ASP.NET 2/23/2004 4:41 PM Jane
This does not seem to work in vb.net, unless I am doing something wrong
# re: How to prevent multiple clicks of a submit button in ASP.NET 2/25/2004 3:37 AM justin
I have implemented the version for pages with required field validators and i have set the button to CausesValidatio="false" yet it still invokes the validators when it is clicked!!!!
# re: How to prevent multiple clicks of a submit button in ASP.NET 3/11/2004 4:49 PM Murry
VB.NET: work whether you have validators on the page or not.
--------- Code in Module1 -------------
Module Module1
Public Sub DisableButton(ByVal btn As System.Web.UI.WebControls.Button)
' 1- On PageLoad add:
' DisableButton(Button1)
'
' 2- On Button1_Click add:
' Threading.Thread.Sleep(1000)
'
' 3- On Button1 Properties set:
' CauseVaidation to false
Dim sJavaScript As String
sJavaScript += "if (typeof(Page_ClientValidate) == 'function') "
sJavaScript += "{ if (Page_ClientValidate() == false) "
sJavaScript += "{ return false; }"
sJavaScript += "} this.value = 'Please wait...';"
sJavaScript += "this.disabled = true;"
sJavaScript += btn.Page.GetPostBackEventReference(btn) & ";"
btn.Attributes.Add("onclick", sJavaScript)
End Sub
End Module
# VB Version 3/22/2004 6:08 PM Joe F
Here's the VB code (translated from above code)
Dim sb As New System.Text.StringBuilder
sb.Append("if (typeof(Page_ClientValidate) == 'function') { ")
sb.Append("if (Page_ClientValidate() == false) { return false; }} ")
sb.Append("this.value = 'Please wait...';")
sb.Append("this.disabled = true;")
sb.Append(Page.GetPostBackEventReference(btnSubmit))
sb.Append(";")
btnSubmit.Attributes.Add("onclick", sb.ToString())
Thanks for the info, this works great.
-Joe
# re: How to prevent multiple clicks of a submit button in ASP.NET 4/5/2004 3:38 PM fdsaf
asdfad
# re: How to prevent multiple clicks of a submit button in ASP.NET 4/13/2004 1:51 PM Girish
The code worked smooth.
Thank you,
# re: How to prevent multiple clicks of a submit button in ASP.NET 4/15/2004 6:42 PM Ash
Do this work for asp.net drop down list?
# re: How to prevent multiple clicks of a submit button in ASP.NET 4/19/2004 11:48 AM CSharper
Awesome! EXACTLY what I was looking for
# More valuable resources #1 4/24/2004 11:16 AM guyS's WebLog
# re: How to prevent multiple clicks of a submit button in ASP.NET 4/28/2004 7:01 AM Laurent
Good job... perfect for me.
# Doesn't work correctly with custom validators! 5/4/2004 5:34 AM tidydave
I have tried you code out... and it work if the page only contains client side validators, but if the page contains a customvalidator that executes on the server a problem occurs.
When you submit the page and the customvalidator evaluates to false e.g. args.IsValid = False, the error message is displayed. When you correct the error and then try and submit the form again.. the button is changed to read "Please wait..." and the button is disabled, but the __doPostBack() function gives the error "Object Expected"
# re: How to prevent multiple clicks of a submit button in ASP.NET 5/8/2004 12:21 AM mkamoski
Does anyone have sample for getting this to work with a LinkButton? I tried and could not get it to disable properly and could not change the text. Any ideas?
# re: How to prevent multiple clicks of a submit button in ASP.NET 6/2/2004 3:43 PM T. Shane Whittet
Here is something to prevent server postbacks for any WebControl and any event. Regards.
whittet at eecs tulane edu
/// <summary>
/// Prevent controls from making multiple server PostBack requests if one is already happening.
/// </summary>
/// <param name="control">A WebControl that causes a server PostBack.</param>
/// <param name="eventType">Type of event, like "onchange" or "onclick".</param>
public static void PreventMultiplePostback(System.Web.UI.WebControls.WebControl control, string eventType)
{
if(!control.Page.IsClientScriptBlockRegistered("bPostbackHappeningNow"))
{
control.Page.RegisterClientScriptBlock("bPostbackHappeningNow",
"<script lang='JavaScript'>var bPostbackHappeningNow = false;</script>");
}
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("if (typeof(Page_ClientValidate) == 'function') { ");
sb.Append("if (Page_ClientValidate() == false) { return false; }} ");
sb.Append("if (bPostbackHappeningNow) return false;");
sb.Append("bPostbackHappeningNow = true;");
control.Attributes.Add(eventType, sb.ToString());
}
# re: How to prevent multiple clicks of a submit button in ASP.NET 6/16/2004 6:49 AM asdfsd
asdfsadfsdfsdf
# re: How to prevent multiple clicks of a submit button in ASP.NET 6/16/2004 6:49 AM asdfsd
asdfsadfsdfsdf
# re: How to prevent multiple clicks of a submit button in ASP.NET 6/16/2004 6:49 AM asdfsd
asdfsadfsdfsdf
# re: How to prevent multiple clicks of a submit button in ASP.NET 6/16/2004 6:50 AM asdfsd
asdfsadfsdfsdf
# re: How to prevent multiple clicks of a submit button in ASP.NET 7/1/2004 3:29 AM Kishore
Why i am getting security exception when i put the user control on my page?
# re: How to prevent multiple clicks of a submit button in ASP.NET 7/14/2004 11:12 AM FINAL ANSWER
If you're new to this page, I sympathize because there's a lot of good information above, but it took me a couple hours to consolidate it and test it. So, I'll post my final function to help you. You can probably start with this (until someone points out the problems with my code).
I'm also adding arguments for controlling the text and colors.
I'm also fixing the problem someone pointed out above about how __DoPostback is not always rendered by the framework and you'd get a javascript "object expected" error. My workaround for this is the line: Page.GetPostBackClientHyperlink
OK. Here's my function, which I also put in a separate class:
Public Shared Sub ConvertToPleaseWaitButton(ByVal btn As System.Web.UI.WebControls.Button, Optional ByVal strText As String = "Please wait...", Optional ByVal strForeColor As String = "White", Optional ByVal strBgColor As String = "Red")
'idea from http://aspzone.com/articles/207.aspx
' 1- On PageLoad add:
'CommonFunction.ConvertToPleaseWaitButton(btnSubmit)
'Page.GetPostBackClientHyperlink(Me, "") 'ensures dopostback function is generated (above function references it but sometimes framework won't generate it)
'
' 2- On Button1_Click add this IF the next page returns quickly:
' Threading.Thread.Sleep(1000) 'to give enough time for people to see "please wait" text before next page
'
' 3- On Button1 Properties set:
' CauseValidation to false 'very important
Dim sJavaScript As String
sJavaScript += "if (typeof(Page_ClientValidate) == 'function') "
sJavaScript += "{ if (Page_ClientValidate() == false) "
sJavaScript += "{ return false; }"
sJavaScript += "} this.value = '" & strText & "';"
sJavaScript += "this.disabled = true;"
sJavaScript += "this.style.color='" & strForeColor & "';"
sJavaScript += "this.style.background='" & strBgColor & "';"
sJavaScript += btn.Page.GetPostBackEventReference(btn) & ";"
btn.Attributes.Add("onclick", sJavaScript)
'Might a 1.1 framework problem with the ":" instead of "_" require the following?
'sJavaScript += Replace(btn.Page.GetPostBackEventReference(btn), ":", "_") & ";"
End Sub
# re: How to prevent multiple clicks of a submit button in ASP.NET 7/15/2004 10:07 AM FINAL ANSWER
Actually, I'll criticize my own code before someone else does. I just learned that once you set the button to disabled, you cannot set the text color. So take your pick of which one is more important to you and change the function accordingly.
Also, my function did not factor in image buttons. I would love to see someone make a similar function that works for image buttons.
And thanks again to the original author for this whole idea.
# re: How to prevent multiple clicks of a submit button in ASP.NET 7/16/2004 11:40 AM John
What about if you dynamically build a button ? Any ideas on how to prevent the double clicking ?
# re: How to prevent multiple clicks of a submit button in ASP.NET 7/16/2004 12:11 PM John
Never mind the code by Joe F works great... Thank you very very much........
# re: How to prevent multiple clicks of a submit button in ASP.NET 7/23/2004 7:37 AM 333
333
# re: How to prevent multiple clicks of a submit button in ASP.NET 7/30/2004 7:47 AM Raj
Does this still work in browsers that does not support javascript or have it disabled?
Nice work!
# re: How to prevent multiple clicks of a submit button in ASP.NET 7/30/2004 12:21 PM Shirish
John and Garry you saved me. Your code works Great
# How to prevent multiple clicks of a submit button in ASP.NET 8/2/2004 12:46 PM fengzhimei
TrackBack From:http://www.cnblogs.com/fengzhimei/archive/2004/08/03/29642.aspx
# How to prevent multiple clicks of a submit button in ASP.NET 8/2/2004 12:46 PM fengzhimei
TrackBack From:http://www.cnblogs.com/fengzhimei/archive/0001/01/01/29642.aspx