一、事件
這是一個長期被我忽略或沒有發現的問題,問題是這樣的:
在一個頁面中,當有驗證控制項的時候,當Button控制項觸發OnClientClick事件,而這個事件會回傳true和false的時候,驗證控制項就會失效,不起作用了。具體描述如下:
.Net頁面如下:
複製代碼代碼如下:
<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事件修改如下:
複製代碼代碼如下:
<asp:Button ID="ButtonText" runat="server" Text="測試" OnClientClick="if(CheckClientValidate()) return Confirm('你確定要提交頁面嗎?');" />
CheckClientValidate()方法的程式碼如下:
複製代碼代碼如下:
<script language="javascript" type="text/javascript">
function CheckClientValidate(){
Page_ClientValidate();
if (Page_IsValid){
return true;
}else{
return false;
}
}
</script>
運行,測試。驗證控制項發揮作用。問題解決。
四、後記
這就是我已知忽略的問題和解決方案,當我發覺這個問題的時候,冒出了一身冷汗,幸虧做了嚴格的伺服器端驗證,不然可就慘了。從這裡也可以看出指定嚴格的伺服器端驗證是多麼的必要啊:-)。它不僅可以防止」駭客「繞過客戶端驗證,還可以防止因為自己沒有發覺的錯誤,造成資料的不準確。
註:
Page_ClientValidate(),本函數用於在包含微軟驗證控制項的aspx頁面中,根據使用者輸入操作是否合法,傳回True或False
可直接判斷。
複製代碼代碼如下:
if(Page_ClientValidate())
{
return true;
}
else
{
return false;
}