How to prevent button double click from server side - c#

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.

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

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

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
}
}

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
}
}
}

Related

Increment variable on page postback and load different pages

I have a property as shown below
private int Step
{
get { return (int)Session["step"]; }
set { Session["step"] = value; }
}
In the Page_Init method, I am initializing it as below
protected void Page_Init(object sender, EventArgs e)
{
if (!IsPostBack)
{
Step = 0;
}
}
In the click event of my save button, I am trying to reload the page as if it was the first time the save button was clicked. If it was the second time the save button was clicked, then redirect to another page.
protected override void cmdNext_Click(object sender, EventArgs args)
{
this.SaveViewModel();
Step++;
if (Step > 1)
{
base.cmdNext_Click(sender, args);
}
else
{
Response.Redirect(Request.RawUrl); //reloading the page again
}
}
The issue is that on the first time the page is reloaded and the Page_Init method sets the variable to 0 again so it never goes past through 1. Can someone please tell me how I can load the same page on the first button click and move on to some other page after the second button click?
Thanks
You can simply check if the Session is null before initializing
protected void Page_Init(object sender, EventArgs e)
{
if (!IsPostBack && Session["step"] == null)
{ Step = 0; }
}

Check to call sql script from different page?

I have two pages - the first page has two buttons and clicking on either of them will run different SQL queries and transfer them to the second page in a GridView. Upon page load, I have two different IF statements: the first one will run the first query and second will run the second query. My question is - how would I do the check to see if that button was clicked?
Here is a sample of my code:
public partial class Page2: System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (page1 button1 is clicked) //this is what I need help with
{
//run sql...
}
else if (page1 button2 is clicked) //this will be similar to the first
{
//run sql...
}
}
}
You could use a session state to store which button was clicked. So in the button event, just have
protected void button1_OnClikc(object sender, EventArgs e)
{
session["WhichButtonWasClicked"] = "Button1";
}
On the Page load of the next page you can read that session value.
If (Session["WhichButtonWasClicked"] == "Button1")
{
// Button 1 is clicked
}
else
{
//Button 2
}
Another option is to pass the button click information as a URL parameter. You could also store the information in a cookie, store it in a DB and retrieve it later. Lots of options!
You can use SESSIONS, when your button is pressed, you should assign a value to a Session variable, for example:
protected void button1_Click(object sender, EventArgs e){
Session["buttonPressed"] = "button1";
// your query and transfer code here
}
protected void button2_Click(object sender, EventArgs e){
Session["buttonPressed"] = "button2";
// your query and transfer code here
}
The session variable will keep the value through the pages, so then use a switch if you want
protected void Page_Load(object sender, EventArgs e)
{
switch (Session["buttonPressed"].ToString())
{
case "button1":
//Your code if the button1 was pressed
break;
case "button2":
//Your code if the button2 was pressed
break;
default:
//Your code if you have a default action/code
break;
}
}

How to handle Checkbox in asp c#

I have a web form in which a check box with code as below
<aspCheckBox ID="txtIsPaid" runat="server" autopostback="true"
OnCheckedChanged="txtIsPaid_CheckedChanged" />
is used.and in sql database datatype is bit.
but when i checked or unchecked this box the value is always false in database. i googled but in vain.
protected void txtIsPaid_CheckedChanged(object sender, EventArgs e)
{
if (txtIsPaid.Checked == true)
{
EmployeeLeave empleave = new EmployeeLeave();
empleave.IsPaid = txtIsPaid.Checked;
}
}
Do this to see if the value is even being changed, and take it from there:
bool isitchecked = txtIsPaid.checked;
Console.WriteLine(isitchecked);
Does your IsPaid setter already run UPDATE SQL?
It seems you don't update to database.
Maybe you must call save function, ex:
protected void txtIsPaid_CheckedChanged(object sender, EventArgs e) {
if (txtIsPaid.Checked == true) {
EmployeeLeave empleave = new EmployeeLeave();
empleave.IsPaid = txtIsPaid.Checked;
empleave.Save();
}
}

Intercept button click on page load

I need to write a code that can intercept a click of some button (asp button) than execute some code, and if a method return true, call the original click.
So the points are:
1- I don´t know how to save the original click.
2- Identify the button that was clicked.
Ex:
protected void Page_Load(object sender, EventArgs e)
{
var b = getButtonThatWasClicked();
var originalClick = b.Click;
if(callSomeMethod(b))
originalClick(null,null);
}
EDIT:
Ok managed to get the button who made the click doing this...Now i need to prevent the original Click to get called. The method bellow didn't worked. Even overriding the original click to a new Handler the old Handler got called and executed. I thing ASP.NET read it and make something like a call stack of events to get called.Even if the handler change the old still in the stack.
public void ButtonsTestMethod()
{
var listOfButtons = listaDeBotes.Where(b => b.CommandName != "");
foreach (var button in listOfButtons)
{
if (Request.Form[button.UniqueID] != null)
{
var buttonFromRequest = Request.Form[button.UniqueID];
if (buttonFromRequest == null)
continue;
if (button.CommandName != "xxx")
{
//validate things
//if(TemPermissao(Tela,GetAcaoDoBotao(botao.CommandName)))
//if(!canexecuteSomething())
button.Click += new EventHandler(defaultClick);
}
}
}
}
void defaultClick(object sender, EventArgs e)
{
//show error
}
protected void Page_Load(object sender, EventArgs e)
{
//other code
ButtonsTestMethod();
}
I don´t know if its possible but would appreciate some help =/
Thanks.
To get the control name, you can try the following in the page load:
protected void Page_Load(object sender, EventArgs e)
{
if( IsPostBack )
{
string senderControl = Request.Params["__EVENTTARGET"].ToString();
//senderControl will contain the name of the button/control responsible for PostBack
}
}
The first argument in the button click event handler is the sender. You can cast that sender as a Button object and then you should be able to identify which button that was based on that object. That way, you can eliminate having that function to figure out which is clicked.
void GreetingBtn_Click(Object sender, EventArgs e)
{
Button clickedButton = (Button)sender;
if(clickedButton.Text == "bla")
{
//Do stuff
}
}

What is the best way to distinguish beteen "Refresh Post" or a "Real Post Back"

What is the best way to distinguish beteen "Refresh Post" or a "Real Post Back".
This is what I need to attain
protected void Button1_Click(object sender, EventArgs e)
{
if(PostBack && !Refresh)
{
//Do Something
}
}
I usually do a Response.Redirect to the same page in the postback event.
That way all my Page.IsPostBack are real Postbacks and not Refreshes
You could set a hidden input with a nonce value generated randomly every time the form is loaded (but not on postback), then check if the nonce value got sent twice. If it got sent a second time, it was a refresh.
you could try like
protected void Button1_Click(object sender, EventArgs e)
{
//your code of Click event
//..............
//...............
// and then add this statement at the end
Response.Redirect(Request.RawUrl); // Can you test and let me know your findings
}
Sample working code for the accepted answer
Add this line in designer
<input type="hidden" runat="server" id="Tics1" value="GGG" />
Add following lined in the code behind
public partial class WebForm1 : System.Web.UI.Page
{
long tics = DateTime.Now.Ticks;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
this.Tics1.Value = tics.ToString();
Session["Tics"] = tics;
}
}
protected void Button1_Click(object sender, EventArgs e)
{
if (Session["Tics"] != null && Request["Tics1"] != null)
{
if (Session["Tics"].ToString().Equals((Request["Tics1"].ToString())))
{
Response.Write("Postback");
}
else
{
Response.Write("Refresh");
}
}
this.Tics1.Value = tics.ToString();
Session["Tics"] = tics;
}
}

Categories