項目中經常出現用戶重復提交的情況,為了防止這種情況,最常用的方法就是在用戶點擊按鈕后將該按鈕設為不可用,筆者在實際開發當中遇到了多種不同的情況,在此做個小結,以供參考。
第一種情況是非submit類型的按鈕
這種情況比較簡單,只要在客戶端添加事件,將按鈕設為不可用就可以了。看下面的代碼:
ASP.NET-Code:
<form id="form1"runat="server"> <asp:Label ID="lbl"runat="server"></asp:Label> <asp:ButtonID="btn" runat="server" Text="Test"OnClick="btn_Click" OnClientClick="this.disabled=true"UseSubmitBehavior="false" /></form>
C#-Code:
protected void btn_Click(object sender,EventArgs e){ System.Threading.Thread.Sleep(1000); lbl.Text =DateTime.Now.ToString();}
第二種情況是submit類型的按鈕
此時第一種方法就不行了,按鈕被設為DISABLED之后就無法完成提交,我們可以適當修改代碼:
ASP.NET-Code:
<form id="form1"runat="server"> <asp:Label ID="lbl" runat="server"></asp:Label><asp:Button ID="btn" runat="server"Text="Test" OnClick="btn_Click"/></form>
C#-Code:
protected void Page_Load(object sender,EventArgs e){ if (!Page.IsPostBack) { btn.OnClientClick ="this.disabled=true;" + GetPostBackEventReference(btn); }}
與第一種方法不同的是我們在Page_Load中給按鈕添加客戶端事件,並附加了GetPostBackEventReference。但這樣做還有個缺 陷,在第一提交回發完成以后,再點擊按鈕就會失敗,因此我們需要去掉if (!Page.IsPostBack)這句,也就是每次回發都要重復綁定客戶端事件。
第三種情況跟第一種類似,只是多了個UpdatePanel
ASP.NET-Code:
<asp:UpdatePanel ID="up1"runat="server" > <ContentTemplate> <asp:LabelID="lbl" runat="server"></asp:Label><asp:Button ID="btn" runat="server"Text="Test" OnClick="btn_Click"OnClientClick="this.disabled=true;" UseSubmitBehavior="false"/> </ContentTemplate></asp:UpdatePanel>
第四種情況也是在UpdatePanel里面,不過和第二種情況一樣,也是Submit類型的按鈕
和第二種情況不同的是,我們只需要在第一次加載的時候綁定客戶端事件就可以了,即在 if (!Page.IsPostBack){}中綁定事件。
第五種和第四種不同的是,按鈕在UpdatePanel外面,通過觸發器來刷新指定的UpdatePanel
如果按第四種的方法,可以在點擊按鈕后設為不可用,但回發完成以后該按鈕不會恢復可用狀態:
ASP.NET-Code:
<asp:UpdatePanel ID="up1"runat="server"> <ContentTemplate> <asp:LabelID="lbl" runat="server"></asp:Label></ContentTemplate> <Triggers> <asp:AsyncPostBackTriggerControlID="btn" EventName="Click" /></Triggers></asp:UpdatePanel><asp:Button ID="btn"runat="server" Text="Test" OnClick="btn_Click"/>
C#-Code:
protected void Page_Load(object sender,EventArgs e){ if (!Page.IsPostBack) { btn.OnClientClick ="this.disabled=true;" + GetPostBackEventReference(btn); }}protectedvoid btn_Click(object sender, EventArgs e){ System.Threading.Thread.Sleep(1000);lbl.Text = DateTime.Now.ToString();}
為了解決這個問題,最簡單的方法就是將該按鈕放在另一個UpdatePanel里面,這樣每次都可以恢復原狀態了。另外還可以根據Atlas的頁面周期,在提交完成以后顯式將該按鈕設為可用。