安安

 

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

posted on 2004-08-03 11:25  心比天高a  阅读(5263)  评论(0)    收藏  举报

导航