ASP.Net双击问题

时间:2009-09-30 13:54:12

标签: c# asp.net javascript onclick double-click

我的ASP.net页面有点问题。如果用户双击“提交”按钮,它将两次写入数据库(即在图像按钮上执行两次'onclick'方法)

如何使用,如果用户点击图像按钮,只是图像按钮被禁用?

我试过了:

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

但是这个OnClientClick属性完全阻止了页面的提交!有什么帮助吗?

对不起,是的,我确实有验证控件......因此问题很糟糕。


现在仍在努力,到目前为止:

ASP代码:

 <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#代码:

         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;

实际上......这几乎可行。双击问题几乎是固定的(耶!)虽然图像仍未隐藏。

6 个答案:

答案 0 :(得分:21)

一般方法是双重的。

<强>了Serverside

  1. 加载页面时,生成令牌(使用System.Random),将其保存在会话中,并将其写入隐藏的表单字段
  2. 在提交时,检查隐藏的表单字段是否等于会话变量(之前再次设置它)
  3. 做好工作
  4. <强>客户机侧

    与您的相似,但可能只是隐藏按钮,并将其替换为“提交”等文字。

    客户端需要注意的重要一点是,用户可以通过点击“转义”来取消帖子,因此您应该考虑在这里做什么(取决于它们不会使用多少令牌,所以你需要将按钮从禁用/隐藏状态恢复。

    完整示例如下:

    C#(包括在行动中查看它的代码):

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

答案 1 :(得分:6)

如果您在页面上进行了验证,则禁用按钮客户端会变得有点棘手。如果验证失败,您不想禁用该按钮。这是一个添加客户端事件处理程序的代码片段:

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());

}

有关详细信息,请参阅此asp.net thread

更新:上面的代码将用于在代码后面添加OnClientClick处理程序。您也可以在aspx标记中编写javascript,如下所示:

<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);" />

答案 2 :(得分:3)

我已经通过在点击服务器之前在客户端点击上设置隐藏字段来解决这个问题。

然后在服务器中我检查隐藏字段,如果值是“FALSE”,那可能意味着我可以或不可以采取行动。

答案 3 :(得分:0)

与Silky的客户端响应类似,我通常制作两个看起来相似的按钮,只是第二个按钮被禁用和隐藏。正常按钮的OnClientClick交换两个按钮的显示样式,以便隐藏正常按钮并显示禁用按钮。

答案 4 :(得分:0)

双击功能是服务器端实现,以防止处理可通过JavaScript在客户端实现的相同请求。该功能的主要目的是防止两次处理相同的请求。服务器端实现通过识别重复请求来完成此操作;但是,理想的解决方案是防止在客户端发生这种情况。

在发送给允许他们提交请求的客户端的HTML内容中,可以使用一个小的验证JavaScript来检查请求是否已经提交,如果是,则阻止在线购物者再次提交请求。此JavaScript验证函数将检查全局标志以查看是否已提交请求,如果已提交;不会重新提交请求。如果在服务器上禁用了双击功能,则强烈建议JSP和HTML页面实现此JavaScript预防。

以下示例通过使用表单对象的onSubmit()操作阻止表单提交多次:

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

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

答案 5 :(得分:0)

对于那些只想快速修复的人,只需隐藏它并显示另一个没有事件的按钮

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