Подтвердить что ты не робот

Проблема с двойным щелчком ASP.Net

имеет небольшую проблему с моей страницей 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';" />

Код С#:

         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;

Собственно... это почти срабатывает. Проблема двойного щелчка в значительной степени исправлена ​​(yay!) Изображение все еще не скрыто.

4b9b3361

Ответ 1

Общий подход двоякий.

Serverside

  • При загрузке страницы создайте токен (используя System.Random), сохраните его в сеансе и запишите в скрытое поле формы
  • В режиме отправки проверьте, что поле скрытой формы равно переменной сеанса (перед ее настройкой)
  • Работать

клиентской

Подобно тому, что у вас есть, но, вероятно, просто спрячьте кнопку и замените ее каким-то текстом, например "отправкой".

Важно отметить, что клиентская сторона заключается в том, что пользователь может отменить сообщение, нажав "escape", поэтому вам следует подумать, что делать здесь (в зависимости от того, насколько далеко они будут использоваться, токен не будет использоваться, поэтому вам нужно будет отключить/отключить кнопку).

Ниже приведен пример:

С# (включает код, чтобы увидеть его в действии):

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

Ответ 2

Если у вас есть проверка на странице, отключение клиентской стороны кнопки немного сложно. Если проверка не удалась, вы не хотите отключать эту кнопку. Здесь фрагмент, который добавляет обработчик событий на стороне клиента:

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 для получения дополнительной информации.

Обновить: приведенный выше код будет использоваться для добавления обработчика OnClientClick в код позади. Вы также можете написать javascript в своей разметке aspx следующим образом:

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

Ответ 3

Я решил это, установив скрытое поле на клиенте, прежде чем нажать на сервер.

Затем на сервере я проверяю скрытое поле и, если это значение, например, что-то "FALSE", что может означать, что я могу или не могу этого сделать.

Ответ 4

Как и на стороне клиентской реакции Silky, я обычно делаю две кнопки, которые выглядят одинаково, за исключением того, что вторая кнопка отключена и скрыта. OnClientClick обычной кнопки меняет стили отображения двух кнопок, так что нормальная кнопка скрыта, и отображается кнопка отключения.

Ответ 5

Функция двойного щелчка представляет собой реализацию на стороне сервера, чтобы предотвратить обработку того же запроса, который может быть реализован на стороне клиента через 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> 

Ответ 6

для тех, кто просто хочет быстро исправить, просто спрячьте его и покажите еще одну кнопку, у которой нет событий

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