ASP.NETで2重クリックを防止するサンプル

はじめに

Webアプリケーションでの基本的な考慮事項の一つとして、
データの2重送信を防止するというものがあります。

もし、2重送信が禁止されていない場合は、
買い物の購入処理で2重に会計してしまったり、
登録処理でデーターの重複などが発生することになります。

そこで、会計処理など2重に送信されてはマズイ場合は、
1回めの処理が完了するまでは、
2回めの処理を行わないようにする必要があるわけです。

今回はASP.NET1.1 + JavaScriptの組み合わせで、
データの2重送信を防止します。

なお、2重送信を防止するアプローチとして、
ASP.NETではサーバーサイドの対応は困難だと思われます。
(少なくとも、クライアントサイドで対応したほうが楽で確実です。)

サンプルコード

.aspx

<!--実際にイベントを起こすボタン-->
<asp:button id="bt_Apply" runat="server" Text="ボタン" 
  Width="120px"></asp:button>
<!--bt_Applyがイベントを起こした後に非表示のボタンとして表示するボタン-->
<asp:button id="dummy" runat="server" Text="ボタン" 
  Width="120px" style="DISPLAY:none" Enabled=False></asp:button>

.js

function EnabledButton()
{
  document.getElementById("bt_Apply").style.display= 'none';
  document.getElementById("dummy").style.display= 'inline';
  return true;
}

.vb(1〜2行目は実際には1行です。)

Private Sub Page_Load(ByVal sender As System.Object, 
  ByVal e As System.EventArgs) Handles MyBase.Load
  ' ページを初期化するユーザー コードをここに挿入します。
  '.NET2.0からはonclientclick属性があるが、1.1にはないので、
  'ロードイベントで、Attributesプロパティにスクリプトを登録する。
  bt_Apply.Attributes("onclick") = "EnabledButton();"
End Sub

解説

手っ取り早くボタンを使用不可にするだけならば、
ボタンクリック時にJavaScriptで、

this.disabled = true;

としてしまえば良いですが、
この方法ではサーバーサイドのonclickイベントが発火しなくなってしまうため却下です。


そこで、使用不可のボタンを予め用意してやり、
クリックされた瞬間に入れ替えるというアプローチを取ります。

流れとしては以下のとおり。

1.bt_Applyがクリックされる。

2.bt_Applyに紐付いているEnabledButton関数が動作し、
  bt_Applyが消える(表示されなくなる)
  bt_Applyが消えた後に、非表示になっていたdummyが表示される。

3.サーバーサイドのボタンクリックイベントが走る

4.その後のポストバックで、初期表示(bt_Applyが表示、dummyが非表示)に戻る

また、ASP.NETのボタンにJavaScriptを追加する必要がありますが
.NET1.1では「OnClientClickプロパティ」は存在しないため、
Attributesプロパティを使用して、ロードイベントでスクリプトを追加してやる必要が有ります。
※OnClientClickプロパティが使えるならそっち推奨。(というか楽)

注意点として.NETでWindowsアプリケーションを作ってきた方の場合、
サーバーサイドのボタンクリックイベントで、
Enable = falseにしてしまえば解決すると考えてしまうかもしれませんが、
今回の2重送信防止に対しては無力です。
(なぜ無力かは考えてみてください)

まとめ

.aspxにダミーのボタンを用意する。

JavaScriptで本物とダミーを切り替える関数を用意する。

.vbでボタンにJavaScriptを追加してやる。