0

I made disable button on javascript button click and it works in most of cases to prevent double click,but in some cases it does not work so I want to prevent double click also from server side.

protected void Page_Load(object sender, EventArgs e)
{
   if(!IsPostBack)
  {
     hfid.value="0";
  }
}
protected void frmSubmit_Click(object sender, EventArgs e)
{
   if(Convert.ToInt32(hfid.value) == 0)
   {
   // Code of insert
   // then I set hfid.value with newly created id
   }
}

 <asp:Button ID="frmSubmitInsert" runat="server" OnClick="frmSubmit_Click" OnClientClick="GRVMasterAddButton_Click(this)" Text="Add"
                                                Width="100px" Visible="false" ValidationGroup="masterGrp" />



 function GRVMasterAddButton_Click(btn)
        {

            if (window.Page_ClientValidate('masterGrp'))
            {
             document.getElementById(btn.id).disabled = true;
                __doPostBack(btn.id, '');
            }

        }

In double click scenario,two times round trip is generated.In First round trip it is ok,but in second round trip though I am setting hfid.value with newly inserted id, it shows me 0 and again duplicate record is generated.

Afshar Mohebi
  • 10,479
  • 17
  • 82
  • 126
Amit Bhatt
  • 45
  • 10
  • Not server side but you can hide button after clicking it !!! – Akash KC Feb 01 '17 at 06:06
  • Check out this earlier question: https://stackoverflow.com/questions/106509/disable-button-on-form-submission Answers suggest both server-side and client-side solutions – default locale Feb 01 '17 at 06:06
  • You can disable or hide the button – Hemal Feb 01 '17 at 06:07
  • Yep, disable button after click, and enable after first operation processing is done – Sergio Feb 01 '17 at 06:25
  • "in some cases it does not work" I am curious as to why this is the case - can you post what you did in JavaScript to disable the button when it's clicked ? – sh1rts Feb 01 '17 at 06:37
  • I have already set button disable in javascript though in some case double click is generated so I want it to prevent also from server side. – Amit Bhatt Feb 01 '17 at 06:53
  • function GRVMasterAddButton_Click(btn) { if (window.Page_ClientValidate('masterGrp')) { document.getElementById(btn.id).disabled = true; __doPostBack(btn.id, ''); } } – Amit Bhatt Feb 01 '17 at 07:01
  • Could it be that the "double click" is in fact a click - post back - click again? That is, the first click does the post back, but then the user clicks again? If so, you should just add code to disable the button in the `frmSubmit_Click` method. If you disable the button in javascript, it will not remain disabled after the postback unless you disable the button in the code behind. – user1429080 Feb 01 '17 at 07:19
  • I checked,once button is clicked twice, setting disable it in frmSubmit_Click() does not work.it again come for second round trip – Amit Bhatt Feb 01 '17 at 07:28
  • Add `return false;` at the end of your javascript function `function GRVMasterAddButton_Click(btn)`, then change your button to have `OnClientClick="return GRVMasterAddButton_Click(this)"` – user1429080 Feb 01 '17 at 07:45

4 Answers4

1

You can use a Session variable in your frmSubmit_Click event handler to ensure server-side that you are not running the submit code twice:

In Form_Load event, add:

Session["isProcessingForm"] = false;

Modify frmSubmit_Click event handler as follows:

protected void frmSubmit_Click(object sender, EventArgs e)
{
   if(Session["isProcessingForm"])
   {
       return;
   }

   Session["isProcessingForm"] = true;

   if(Convert.ToInt32(hfid.value) == 0)
   {
       // Code of insert
       // then I set hfid.value with newly created id
   }

   //Once form is processed
   Session["isProcessingForm"] = false;
}

If this application runs on a web farm (multiple web servers), you'll need to persist session state. There are several ways to do so in ASP.NET WebForms. More info here: https://msdn.microsoft.com/en-us/library/ms178581.aspx and here: https://msdn.microsoft.com/en-us/library/ms178587.aspx

CoolBots
  • 4,770
  • 2
  • 16
  • 30
0

Best option is disable button in client side using javascript in very first click

Damith Asanka
  • 934
  • 10
  • 12
  • OP is specifically asking for a server-side solution. It is stated in the question that JavaScript disabling is already in place. – CoolBots Feb 01 '17 at 06:39
  • @CoolBots you are right,I want to prevent it from server side,I already disable it from client side. – Amit Bhatt Feb 01 '17 at 07:33
0

Try the following: It should definitely work.

    protected void Page_Load(object sender, EventArgs e)
        {
                 if(!IsPostBack)
                 {
                    hfid.value="0";
                 }
            frmSubmit.Attributes.Add("onclick", "this.disabled = true; this.value = 'Loading ...'; " + ClientScript.GetPostBackEventReference(frmSubmit, null) + ";");
        }

     protected void frmSubmit_Click(object sender, EventArgs e)
        {
            //Remove following line, this is added just to test.
            System.Threading.Thread.Sleep(5000);
            if (Convert.ToInt32(hfid.Value) == 0)
            {
                // Code of insert
                // then I set hfid.value with newly created id
            }
        }
Shiva K Thogiti
  • 208
  • 2
  • 6
  • this will disable the button just before submitting and remain disabled until the postback is complete – Shiva K Thogiti Feb 01 '17 at 07:11
  • `Page_Load` is run on every request - `hfid.Value` will always be set to zero in your example code. Additionally, this still relies on a client-side disabing of the button, which can take time to take effect (cost of the round-trip). The button can be clicked multiple times prior to being disabled, even if the code is corrected to persist the value and not reset it on postbacks. – CoolBots Feb 01 '17 at 08:07
  • No, this will not wait for the page load to run... please try and see. From client side I am disabling the button as and when it is clicked. – Shiva K Thogiti Feb 01 '17 at 09:16
  • Ok, that's true - you're setting that on the initial page load; it's still a client-side solution, and your `hfid.Value` still gets reset on every reload - basically the 2nd line in `Page_Load` and the `if` check in the `frmSubmit_Click` are useless code, as the `if` check will always return true – CoolBots Feb 01 '17 at 09:20
  • Yep CoolBots, sorry. Got your point now. I was concentrating on disabling button while postback. Yes, isPostBack condition has be in place to make sure hid.Value is not overridden every time :) – Shiva K Thogiti Feb 01 '17 at 10:00
-2

You can use Lock. To prevent multiple call at same time.

private object _lockObj = new object();
protected void frmSubmit_Click(object sender, EventArgs e)
{
    // Here we lock code. When someone else will try to access to this code
    // or in your case double clicked button it will wait until _lockObj
    // is set to free.
    Lock(_lockObj)
    {
        if(Convert.ToInt32(hfid.value) == 0)
        {
        // Code of insert
        // then I set hfid.value with newly created id
        }
    }
}
Sergio
  • 346
  • 1
  • 8
  • That won't work, as the lock object will be destroyed per each request. See ASP.NET Page LifeCycle: https://msdn.microsoft.com/en-us/library/ms178472.aspx – CoolBots Feb 01 '17 at 06:37
  • This will prevent any other thread entering the locked region, which for a website is a sure-fire way to hurt scalability. Also, you're not instantiating `_lockObj` before use, so this will not even compile. – sh1rts Feb 01 '17 at 06:39
  • @CoolBots It will work perfectly. The _lockObj is global @sh!rts thanks for remind. And hey, isn't he want that no one touch this part of code twice in same time? Mistakes in his logic and structure it's actually he's problem. He ask HOW TO PREVENT DOUBLE CALL (CLICK) So a believe both downvotes are not fair... – Sergio Feb 01 '17 at 06:44
  • @sh1rts, actually it just won't work, even if corrected to compile - each page request instantiates a new ASP.NET Page object, which is destroyed once the request is completed - the lock object is useless. – CoolBots Feb 01 '17 at 06:45
  • @Sergio, the lock object is global **to the class that gets created and destroyed on each request** - this is web, not desktop programming! Even your comment is incorrect: "When someone else will try to access to this code or in your case double clicked button it will wait until _lockObj is set to free." - completely wrong! - **a brand new instance of this Page object is created** with its own lock! Unless you make it `static`, which would be even worse, as then only 1 user could click the button at any given time, for the entire web application! – CoolBots Feb 01 '17 at 06:52
  • Any one know why I am getting hfid.value is 0 in second round trip though I set it in first round trip? – Amit Bhatt Feb 01 '17 at 07:35
  • @AmitBhatt, because the Page object is destroyed and re-created on every request. There is no way to preserve variable state this way on the web - you need session state handling! See my answer, and more info here: https://msdn.microsoft.com/en-us/library/75x4ha6s.aspx – CoolBots Feb 01 '17 at 08:01