ASP.NET дважды щелкает по проблеме

Выезд joe-e, реализация возможностей Java.

23
задан Bill the Lizard 25 August 2011 в 19:13
поделиться

5 ответов

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

Серверная сторона :

  1. При загрузке страницы сгенерируйте токен (используя System.Random ), сохраните его в сеансе и запишите его в скрытое поле формы
  2. При отправке убедитесь, что поле скрытой формы совпадает с переменной сеанса ( перед повторной настройкой )
  3. Do work

Clientside :

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

На стороне клиента важно отметить, что пользователь может отменить публикацию, нажав «escape», поэтому вам следует подумать, что делать здесь ( в зависимости от того, насколько далеко они продвинулись, токен не будет использоваться, поэтому вам нужно вернуть кнопку из состояния отключения / скрытия).

Полный пример приведен ниже:

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>
21
ответ дан 29 November 2019 в 02:36
поделиться

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

Затем на сервере я проверяю скрытое поле, и если значение, например, «ЛОЖНО», это может означать, что я могу или не могу действия.

3
ответ дан 29 November 2019 в 02:36
поделиться

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

0
ответ дан 29 November 2019 в 02:36
поделиться

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

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

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);" />
6
ответ дан 29 November 2019 в 02:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: