UseSubmitBehaviot 屬性是控制Button於HTML輸出時Type是否為submit或Button屬性
在ASP.NET的Button控制項中預設是會去執行postback,也就是會在submit時會自動去執行__doPostBack 函式
而如果在Button設定UseSubmitBehaviot=false時,Button必須在onClick事件中自行去呼叫__doPostBack 函式
於HTML原始碼下如以下:
UseSubmitBehavior=true
<input type="submit" name="Button1" value="Button" id="Button1" />
UseSubmitBehavior=false
<input type="button" name="Button2" value="Button" onclick="javascript:__doPostBack('Button2','')" id="Button2" />
可以發現usesubmitbehavior=false時是執行onclick呼叫__doPostBack函式
而當使用usesubmitbehavior=false時,可使用GetPostBackEventReference方法加入一段JavaScript程式碼返回Client端執行
例如加入confirm 彈出視窗來讓使用者確認跟現在要使用防止使用者重複點擊送出按鈕方法
以下程式碼為加入防止使用者重複點擊送出按鈕的方法:
Step 1:
於 .aspx 頁面中加入Button 並設定useSubmitBehaviot=false,和一個Label
Step 2:
於 Code Behind 中加入以下程式碼,在Page_Load時為Button1附加onclick事件並使用GetPostBackEventReference方法來註冊JavaScript程式碼
在JavaScript程式碼中將 Button 做 disable 並更改文字為"儲存中"
Step 3:
於 Code Behind 的 Button Click事件中讓程式Sleep 2秒後開始執行程式碼
Step 4:
完成以上步驟後,實際去執行aspx網頁並點擊Button則會發現此時Button變成暗色無法點選,如此就可以防止使用者重複點擊送出情形
2011/12/03 補充:
如在post server端前要綁javascript驗正時可寫一個驗正function並回傳true/false,而code behind註冊onclick時更改為以下
1 |
this .Button1.Attributes.Add( "onClick" , "if (checkField()) {" + this .GetPostBackEventReference(Button1, "Click" ) + ";this.disabled=true;this.value='儲存中';this.style.width=60;}else{return false;}" ); |
2011/12/25補充:
以上的寫法看似好像沒有問題,不過實際上在Windows事件檢視器會發現每當點擊一次按鈕就會產生一個錯誤訊息,如下
Event code: 3005 Event message: 發生未處理的例外狀況。
Event time: 2011/12/25 下午 11:54:33
Event time (UTC): 2011/12/25 下午 03:54:33
Event ID: e588a2786881407a957190ecf6fc2f88 Event sequence: 71
Event occurrence: 7 Event detail code: 0
.......
.......
Exception information: Exception type: ArgumentException Exception message: 無效的回傳或回呼引數。已在組態中使用 或在網頁中使用 <%@ page="" enableeventvalidation="true">啟用事件驗證。基於安全性理由,這項功能驗證回傳或回呼引數是來自原本呈現它們的伺服器控制項。如果資料為有效並且是必需的,請使用 ClientScriptManager.RegisterForEventValidation 方法註冊回傳或回呼資料,以進行驗證。
.......
.......
原因是因為呼叫了GetPostBackEventReference方法,導致Button1與原本的事件驗證脫離,
網路上大部分的解法都是說將 EnableEventValidation 屬性設定為 false,關閉EnableEventValidation的驗證模式,
但是這個方法其實並不恰當,ASP.NET 的事件驗證機制是用來防止惡意程式攻擊,關閉了事件驗證機制等於少了本身的防範機制,會讓網站置於危險的風險下
並且有可能導致其他控制項的失效及問題。
所以在這邊我改寫原本的方法,使用RegisterForEventValidation 將Button1重新註冊驗證機制,如下
RegisterForEventValidation 方法必須於Page_Render中註冊,第一步我覆寫Render事件,於Page中加入以下程式碼
1 |
protected override void Render(System.Web.UI.HtmlTextWriter writer) |
2 |
{ |
3 |
4 |
} |
並在Render中註冊RegisterForEventValidation及GetPostBackEventReference,由於撰寫Page.ClientScript.RegisterForEventValidation時,會提示這個方法已經過時,所以現在改使用ClientScriptManager類別方法
1 |
protected override void Render(System.Web.UI.HtmlTextWriter writer) |
2 |
{ |
3 |
ClientScriptManager cs = Page.ClientScript; |
4 |
cs.RegisterForEventValidation(Button1.UniqueID, "click" ); |
5 |
this .btnSave.Attributes.Add( "onclick" , cs.GetPostBackEventReference(Button1, "click" ) + ";this.disabled=true;" ); |
6 |
base .Render(writer); |
7 |
} |
RegisterForEventValidation方法的第一個參數為 Control 的 UniqueID, 第二個參數為事件引數,在GetPostBackEventReference方法中我使用"click",所以在這必須填入一樣的事件引數。
當修改成以上程式碼後,在HTML頁中Button1的useSubmitBehaviot屬性需要設定為true或刪除才可以正常執行,如未刪除則會出現重複Postback的情況發生,當修改完成後接著測試按鈕在回 Windows事件檢視器 中查看
會發現已經無以上的錯誤訊息出現,因為已經使用RegisterForEventValidation方法,重新將Button1註冊事件驗證。
外部參考:
http://www.dotblogs.com.tw/joysdw12/archive/2011/11/22/58961.aspx
留言列表