一、事件
這是一個長期被我忽略或者是沒有發現的問題,問題是這樣的:
在一個頁面中,當有驗證控制項的時候,當Button控制項觸發OnClientClick事件,並且這個事件會返回true和false的時候,驗證控制項就會失效,不起作用了。具體描述如下:
.Net頁面如下:
Code
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
<asp:TextBox ID="TextBoxTest" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="TextBoxTest"
ErrorMessage="不可為空" Display="None"></asp:RequiredFieldValidator><ajaxToolkit:ValidatorCalloutExtender
ID="ValidatorCalloutExtender1" TargetControlID="RequiredFieldValidator1" runat="server">
</ajaxToolkit:ValidatorCalloutExtender>
<asp:Button ID="ButtonText" runat="server" Text="測試" OnClientClick="return confirm('你確定要提交嗎?');" />
</div>
</form>
如上,在頁面中加入RequireFieldValidator驗證控制項,使TextBoxTest的值不可為空,在ButtonText提交頁面時,要使用者確認是否需要提交。很簡單的一個頁面,貌似也沒有什麼問題。可是當TextBoxTest的值為空白的時候,驗證控制項竟然不起作用,提交頁面成功。這是什麼原因呢?
二、響應事件
這是怎麼回事呢?首先我將ButtonTest的OnClientClick事件去掉後,驗證控制項是起作用的。這又是為什麼呢?我查看了頁面的原始碼,發現ButtonTest控制項產生如下原始碼:
<input type="submit" name="ButtonText" value="測試" onclick="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ButtonText", "", true, "", "", false, false))" id="ButtonText" />
從這行原始碼可以看出,驗證控制項在用戶端產生了一段javascript代碼,驗證TextBox中的值是否為空白。當我加上ButtonTest的OnClientClick後,我重新查看了原始碼,ButtonTest控制項產生的原始碼如下:
<input type="submit" name="ButtonText" value="測試" onclick="return confirm('你確定要提交嗎?');WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ButtonText", "", true, "", "", false, false))" id="ButtonText" />
從這行代碼中,可以非常清楚的看到問題處在什麼地方了,在用戶端,首先執行的是自訂的javascript,然後在執行驗證控制項產生的這一段javascript,顯然,在這種情況下,驗證控制項就失去任何意義了。
三、響應控制項
知道了問題處在什麼地方,就好辦了,我的解決辦法是:在執行自訂的javascript(return confirm('你確定要提交嗎?‘)前 ,就要驗證頁面中的控制項是否符合規則,於是我將ButtonTest的OnClientClick事件修改如下:
Code
<asp:Button ID="ButtonText" runat="server" Text="測試" OnClientClick="if(CheckClientValidate()) return Confirm('你確定要提交頁面嗎?');" />
CheckClientValidate()方法的代碼如下:
Code
<script language="javascript" type="text/javascript">
function CheckClientValidate(){
Page_ClientValidate();
if (Page_IsValid){
return true;
}else{
return false;
}
}
</script>
運行,測試。驗證控制項發揮作用。問題解決。
四、後記
這就是被我已知忽略的問題和解決方案,當我發覺這個問題的時候,冒出了一身冷汗,幸虧做了嚴格的伺服器端驗證,不然可就慘了。從這裡也可以看出指定嚴格的伺服器端驗證是多麼的有必要啊:-)。它不僅可以防止”駭客“繞過用戶端驗證,還可以防止因為自己沒有發覺的錯誤,造成資料的不準確。
這是我的解決方案,不是園友們是否還有其他的解決方案,歡迎交流。