23

私のASP.netページにわずかな問題があります。ユーザーが「送信」ボタンをダブルクリックすると、データベースに 2 回書き込みます (つまり、imagebutton で「onclick」メソッドを 2 回実行します)。

ユーザーがイメージボタンをクリックすると、イメージボタンだけが無効になるようにするにはどうすればよいですか?

私はもう試した:

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

実際...これはほとんど機能します。ダブルクリックの問題はほとんど修正されました (やった!) 画像はまだ非表示になっていません。

4

6 に答える 6

21

一般的なアプローチは 2 つあります。

サーバー側:

  1. ページのロード時に、( を使用してSystem.Random) トークンを生成し、セッションに保存して、非表示のフォーム フィールドに書き込みます。
  2. 送信時に、非表示のフォーム フィールドがセッション変数と等しいことを確認します (再度設定する前に)。
  3. 仕事する

クライアント側:

あなたが持っているものと似ていますが、おそらくボタンを隠して、「送信中」のようなテキストに置き換えてください。

クライアント側で注意すべき重要なことは、ユーザーが「エスケープ」を押して投稿をキャンセルする可能性があることです。そのため、ここで何をすべきかを検討する必要があります (ユーザーがどこまで進んでいるかによっては、トークンが使用されないため、ボタンを無効/非表示から戻す必要があります)。

完全な例は次のとおりです。

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>
于 2009-09-30T13:57:37.977 に答える
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 スレッドを参照してください。

更新: 上記のコードは、コード ビハインドで 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);" />
于 2009-09-30T14:11:04.453 に答える
3

サーバーにアクセスする前に、クライアントのクリックで隠しフィールドを設定することで、これを解決しました。

次に、サーバーで隠しフィールドをチェックし、値がたとえば「FALSE」である場合、アクションを実行できるかできないかを意味します。

于 2009-09-30T13:58:44.037 に答える
0

ダブルクリック機能は、JavaScript を介してクライアント側で実装できる同じ要求の処理を防ぐためのサーバー側の実装です。この機能の主な目的は、同じリクエストが 2 回処理されるのを防ぐことです。サーバー側の実装は、繰り返されるリクエストを識別することによってこれを行います。ただし、理想的な解決策は、クライアント側でこれが発生しないようにすることです。

リクエストの送信を許可するクライアントに送信される 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> 
于 2009-10-01T09:15:28.840 に答える
0

Silky のクライアント側の応答と同様に、私は通常、2 番目のボタンが無効で非表示になっていることを除いて、よく似た 2 つのボタンを作成します。通常のボタンの OnClientClick は、2 つのボタンの表示スタイルを入れ替えて、通常のボタンを非表示にし、無効なボタンを表示します。

于 2009-09-30T14:31:40.107 に答える
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>
于 2016-06-20T17:20:26.910 に答える