2009-09-30 9 views
23

mit einem kleinen Problem mit meiner ASP.net-Seite von mir. Wenn ein Benutzer auf einen "Senden" -Knopf doppelklickt, wird er zweimal in die Datenbank schreiben (dh zweimal die "onclick" -Methode auf der imagebutton ausführen)ASP.Net Doppelklick-Problem

Wie kann ich es machen, wenn ein Benutzer klickt die Bildschaltfläche, nur die Bildschaltfläche ist deaktiviert?

Ich habe versucht:

<asp:ImageButton 
    runat="server" 
    ID="VerifyStepContinue" 
    ImageUrl=image src 
    ToolTip="Go" 
    TabIndex="98" 
    CausesValidation="true" 
    OnClick="methodName" 
    OnClientClick="this.disabled = true;" /> 

Aber diese OnClientClick Eigenschaft stoppt vollständig die Seite von vorgelegt werden! Irgendeine Hilfe?

Entschuldigung, ja, ich habe Validierungskontrollen ... daher das eklige Problem.


noch auf diese Arbeiten, bis jetzt zu diesem Punkt:

ASP-Code:

<asp:TextBox ID="hidToken" runat="server" Visible="False" Enabled="False"></asp:TextBox> 
... 
<asp:ImageButton runat="server" ID="InputStepContinue" Name="InputStepContinue" ImageUrl="imagesrc" ToolTip="Go" TabIndex="98" CausesValidation="true" OnClick="SubmitMethod" OnClientClick="document.getElementById('InputStepContinue').style.visibility='hidden';" /> 

C# -Code:

  private Random 
    random = new Random(); 


    protected void Page_Load(object sender, EventArgs e) 
    { 
     //Use a Token to make sure it has only been clicked once. 
     if (Page.IsPostBack) 
     { 
      if (double.Parse(hidToken.Text) == ((double)Session["NextToken"])) 
      { 
       InputMethod(); 
      } 
      else 
      { 
       // double click 
      } 
     } 

     double next = random.Next(); 

     hidToken.Text = next + ""; 
     Session["NextToken"] = next; 

Eigentlich ... dies fast funktioniert. Das Doppelklick-Problem ist ziemlich fest (yay!) Das Bild ist aber immer noch nicht versteckt.

Antwort

21

Der allgemeine Ansatz ist zweifach.

Server:

  1. Auf Last der Seite, ein Token generiert (mit System.Random), ist es in der Sitzung speichern, und es zu einem Feld versteckten Form schreibt
  2. On einreichen, prüfen Sie, ob das versteckte Formularfeld gleich der Session-variablen (vor es wieder setzen)
  3. arbeiten sie

Kundenseite:

Ähnlich wie das, was Sie haben, aber wahrscheinlich nur die Schaltfläche ausblenden, und ersetzen Sie sie mit etwas Text wie "Senden".

Die wichtige Sache zu beachten, Client-Seite, ist, dass der Benutzer den Beitrag durch Drücken von "Escape" abbrechen können, so sollten Sie überlegen, was Sie hier tun (abhängig davon, wie weit sie das Token nicht verwendet werden , also müssen Sie die Schaltfläche zurückstellen, damit sie deaktiviert/ausgeblendet wird).

Komplettes Beispiel folgt:

C# (Code enthält es in Aktion zu sehen):

<html> 
<head runat="server"> 
    <title>double-click test</title> 
    <script language="c#" runat="server"> 
    private Random 
     random = new Random(); 

    private static int 
     TEST = 0; 

    public void Page_Load (object sender, EventArgs ea) 
    { 
     SetToken(); 
    } 

    private void btnTest_Click (object sender, EventArgs ea) 
    { 
     if(IsTokenValid()){ 
      DoWork(); 
     } else { 
      // double click 
      ltlResult.Text = "double click!"; 
     } 
    } 

    private bool IsTokenValid() 
    { 
     bool result = double.Parse(hidToken.Value) == ((double) Session["NextToken"]); 
     SetToken(); 
     return result; 
    } 

    private void SetToken() 
    { 
     double next = random.Next(); 

     hidToken.Value  = next + ""; 
     Session["NextToken"] = next; 
    } 


    private void DoWork() 
    { 
     TEST++; 
     ltlResult.Text = "DoWork(): " + TEST + "."; 
    } 
    </script> 
</head> 
<body> 
    <script language="javascript"> 
     var last = null; 
     function f (obj) 
     { 
      obj.src = "http://www.gravatar.com/avatar/4659883ec420f39723c3df6ed99971b9?s=32&d=identicon&r=PG"; 
      // Note: Disabling it here produced strange results. More investigation required. 
      last = obj; 
      setTimeout("reset()", 1 * 1000); 
      return true; 
     } 

     function reset() 
     { 
      last.src = "http://www.gravatar.com/avatar/495ce8981a5127a9fd24bd72e7e3664a?s=32&d=identicon&r=PG"; 
      last.disabled = "false"; 
     } 
    </script> 
    <form id="form1" runat="server"> 
     <asp:HiddenField runat="server" ID="hidToken" /> 
     <asp:ImageButton runat="server" ID="btnTest" 
      OnClientClick="return f(this);" 
      ImageUrl="http://www.gravatar.com/avatar/495ce8981a5127a9fd24bd72e7e3664a?s=32&d=identicon&r=PG" OnClick="btnTest_Click" /> 
     <pre>Result: <asp:Literal runat="server" ID="ltlResult" /></pre> 
    </form> 
</body> 
</html> 
+0

+1. nice ....... –

+2

Es gibt keine eingebaute, einfache Möglichkeit, dieses Problem in ASP.Net zu behandeln? – MusiGenesis

+0

MusiGenesis: Alles, was ich weiß, ist, ich habe jetzt 7777 rep und ich will nie ein einziges Bit mehr (http://www.ffonline.com/media/guides/ff7/ffvii_faq_lucky7.txt) (Und nein). –

3

ich diese gelöst durch ein verstecktes Feld auf dem Client-Klick Einstellung, bevor Sie den Server zu treffen.

Dann auf dem Server überprüfe ich das versteckte Feld und wenn der Wert zum Beispiel etwas 'FALSCH' ist, kann das bedeuten, dass ich kann oder nicht von der Aktion.

6

Wenn Sie eine Validierung auf der Seite haben, wird die Deaktivierung der Schaltfläche Clientseite ein wenig schwierig. Wenn die Validierung fehlschlägt, möchten Sie die Schaltfläche nicht deaktivieren. Hier ist ein Ausschnitt, der die Client-Seite Ereignishandler fügt hinzu:

private void BuildClickOnceButton(WebControl ctl) 

{ 

System.Text.StringBuilder sbValid = new System.Text.StringBuilder(); 

sbValid.Append("if (typeof(Page_ClientValidate) == 'function') { "); 

sbValid.Append("if (Page_ClientValidate() == false) { return false; }} "); 

sbValid.Append(ctl.ClientID + ".value = 'Please wait...';"); 

sbValid.Append(ctl.ClientID + ".disabled = true;"); 

// GetPostBackEventReference obtains a reference to a client-side script 
// function that causes the server to post back to the page. 

sbValid.Append(ClientScript.GetPostBackEventReference(ctl, "")); 

sbValid.Append(";"); 

ctl.Attributes.Add("onclick", sbValid.ToString()); 

} 

diesen asp.net thread Siehe für weitere Informationen.

Update: Der obige Code würde verwendet, um den OnClientClick-Handler in Code hinter hinzuzufügen. Sie könnten auch die Javascript in Ihrem aspx Markup schreiben wie so:

<script type="text/javascript"> 
function disableButton(button) 
{ 
    // if there are client validators on the page 
    if (typeof(Page_ClientValidate) == 'function') 
    { 
     // if validation failed return false 
     // this will cancel the click event 
     if (Page_ClientValidate() == false) 
     { 
      return false; 
     } 
    } 

    // change the button text (does not apply to an ImageButton) 
    //button.value = "Please wait ..."; 
    // disable the button 
    button.disabled = true; 

    // fire postback 
    __doPostBack(button.id, ''); 
} 
</script> 

<asp:ImageButton runat="server" ID="VerifyStepContinue" ImageUrl="button.png" 
    ToolTip="Go" TabIndex="98" CausesValidation="true" OnClick="methodName" 
    OnClientClick="return disableButton(this);" /> 
+0

Das sieht aus wie ich bin, aber nicht ganz sicher, wie man damit arbeitet ... welche Variablen müsste ich für meine ändern? Ich habe mir den Forenbeitrag angeschaut und es scheint richtig zu sein, aber ich kann es nicht ganz verstehen. –

+0

Ich habe meine Antwort mit einem Beispiel aktualisiert. Hoffe das hilft! – jrummell

+0

Noch einmal, funktioniert nicht ... wenn ich versuche, dies zu verwenden, deaktiviert es immer noch alles. –

0

ähnlich Silky des clientseitige Antwort, ich in der Regel zwei Tasten machen, die mit Ausnahme gleich aussehen, dass die zweite Schaltfläche deaktiviert und versteckt. OnClientClick der normalen Schaltfläche vertauscht die Anzeigestile der beiden Schaltflächen, sodass die normale Schaltfläche ausgeblendet und die deaktivierte Schaltfläche angezeigt wird.

0

Die Doppelklickfunktion ist eine serverseitige Implementierung, um die Verarbeitung der gleichen Anforderung zu verhindern, die auf der Clientseite über JavaScript implementiert werden kann. Der Hauptzweck dieser Funktion besteht darin, die Verarbeitung derselben Anfrage zweimal zu verhindern. Die serverseitige Implementierung führt dies durch Identifizieren der wiederholten Anforderung durch; Die beste Lösung ist jedoch, dies auf der Client-Seite zu verhindern.

Im HTML-Inhalt, der an den Client gesendet wird, um Anfragen zu senden, kann ein kleines Validierungs-JavaScript verwendet werden, um zu überprüfen, ob die Anfrage bereits abgeschickt wurde. Falls dies der Fall ist, kann der Online-Käufer die Anfrage nicht erneut einreichen. Diese JavaScript-Validierungsfunktion prüft das globale Flag, um festzustellen, ob die Anfrage gesendet wurde, und wenn dies der Fall ist; Übermittelt die Anfrage nicht erneut. Wenn die Doppelklickfunktion auf dem Server deaktiviert ist, wird dringend empfohlen, dass die JSP- und HTML-Seiten diese JavaScript-Vorbeugung implementieren.

Das folgende Beispiel verhindert, dass die Form von mehr als einmal vorgelegt werden durch die onSubmit() -Aktion des Formularobjekts mit:

... 
<script> 
var requestSubmitted = false; 
     function submitRequest() { 
       if (!requestSubmitted) { 
        requestSubmitted = true; 
        return true; 
       } 
       return false; 
     } 
</script> 
... 

     <FORM method="POST" action="Logon" onSubmit="javascript:submitRequest()"> 
       ...... 
     </FORM> 
+0

Der onsubmit-Code sollte wie folgt aussehen: onsubmit = "return submitRequest()". –

0

für diejenigen, die nur eine schnelle Lösung tun wollen, verstecken es nur und zeigen Sie eine andere Taste, die keine Ereignisse hat

<asp:Button ID="RedeemSubmitButton" runat="server" Text="Submit to Redeem" OnClick="RedeemSubmitButton_Click" OnClientClick="hideit();" /> 
<asp:Button ID="RedeemSubmitButtonDisabled" style="display:none;" runat="server" Text="please wait" OnClientClick="javascript:alert('please wait, processing');" /> 
<script> 
function hideit() { 



     var btn = $get('<%= this.RedeemSubmitButton.ClientID %>'); 
     var btn2 = $get('<%= this.RedeemSubmitButtonDisabled.ClientID %>'); 
     if (btn != null) 
     { 

      btn.style.display = 'none'; 
      btn2.style.display = 'block' 
     } 
} 
    </script>