ASP.NET Button控件的UseSubmitBehavior属性引发的血案
這里先不說(shuō)標(biāo)題上的UseSubmitBehavior屬性是什么,先說(shuō)下面這種情況。
通常,在我們寫(xiě)一個(gè)表單頁(yè)面的時(shí)候,最下方會(huì)有“提交”和“返回”字樣的兩個(gè)按鈕。顧名思義,它們的功能大家都知道,但是一般情況下我們會(huì)給表單的內(nèi)容加上一些驗(yàn)證,這樣就出現(xiàn)了一個(gè)問(wèn)題。因?yàn)閮蓚€(gè)按鈕是服務(wù)器控件(有runat=”Server”屬性),所以點(diǎn)擊按鈕之后會(huì)先進(jìn)行驗(yàn)證(無(wú)論這里你用的是前臺(tái)的jQuery.validate驗(yàn)證或者是ASP.NET自帶的后臺(tái)驗(yàn)證控件驗(yàn)證,都會(huì)先進(jìn)行驗(yàn)證)。對(duì)于“提交”按鈕,這確實(shí)是我們想要的,但是對(duì)于“返回”按鈕,我們并不想出現(xiàn)這種情況,而是想讓它不經(jīng)過(guò)驗(yàn)證,直接跳轉(zhuǎn)回上一頁(yè)。
對(duì)于這種情況,我以前的解決方法就是把
| 1 | <asp:Button?ID="button_back"?runat="server"?Text="back"?OnClick="button_back_Click"?/> |
換成
| 1 | <input?type="button"?value="back"?onclick="BackToPage();"?/> |
這種形式。BackToPage方法實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)。
我相信很多朋友都是這么寫(xiě)的吧?反正能解決問(wèn)題就行。為什么?往下看。
但是今天無(wú)意中發(fā)現(xiàn)了Button.UseSubmitBehavior這個(gè)屬性,將其置成false,會(huì)使“返回”按鈕“躲避”掉表單驗(yàn)證,直接執(zhí)行點(diǎn)擊事件中的方法。這正是我們一直以來(lái)想要的不是么?而且按鈕還很統(tǒng)一,不用去加額外的js代碼。
這里要說(shuō)明一下,大家不要以為Button.UseSubmitBehavior真的是用來(lái)“躲避”驗(yàn)證的,我只是用這個(gè)詞來(lái)表達(dá)一下它實(shí)現(xiàn)的效果。實(shí)際上Button控件有專(zhuān)門(mén)的屬性是用來(lái)屏蔽驗(yàn)證控件的。就是Button.CausesValidation,通過(guò)名字我們應(yīng)該就能了解一二。
那你會(huì)不會(huì)問(wèn),“既然有這個(gè)屬性,以上問(wèn)題就不算是問(wèn)題啦,可以很容易的解決。”
我想說(shuō),“是這樣的啊!”但前提是,你的項(xiàng)目中只存在后臺(tái)驗(yàn)證。但是現(xiàn)實(shí)中我覺(jué)得不會(huì)所有人都這樣做吧?反正我就蠻習(xí)慣用jQuery.validate驗(yàn)證插件的(前臺(tái)驗(yàn)證)。那我們繼續(xù)研究Button.UseSubmitBehavior吧。
看個(gè)例子:
前臺(tái)代碼:
| 1 2 | <asp:Button?ID="button_confirm"?runat="server"?Text="確定"?/> <asp:Button?ID="button_back"?runat="server"?Text="返回"?onclick="button_back_Click"?/> |
瀏覽器中查看源碼中的形式
前臺(tái)代碼:
| 1 2 | <asp:Button?ID="button_confirm"?runat="server"?Text="確定"?/> <asp:Button?ID="button_back"?runat="server"?Text="返回"?UseSubmitBehavior="false"?onclick="button_back_Click"?/> |
瀏覽器中查看源碼中的形式
大家可以看出加上UseSubmitBehavior屬性后,解析成的html語(yǔ)句明顯不同。看到這我才恍然大悟,當(dāng)加過(guò)UseSubmitBehavior屬性之后,type屬性變成了button,這樣就跟以往的解決方法一樣了啊,因?yàn)椴皇莝ubmit屬性,所以也就不會(huì)觸發(fā)jQuery.validate的驗(yàn)證方法(回答上面橙色加粗部分的為什么)。這就是為什么UseSubmitBehavior?置成false后,不用去進(jìn)行前臺(tái)驗(yàn)證的原因。這就是謎底。
但是到這就結(jié)束了會(huì)不會(huì)覺(jué)得有些怪呢?我們?yōu)榱诉_(dá)到我們的目的,使用了一個(gè)新的屬性,但是這個(gè)屬性存在的意義并非是為了達(dá)到我們的目的。
整理一下思緒,上面的例子我們需要從腦袋里抹去。UseSubmitBehavior屬性與是否觸發(fā)表單驗(yàn)證完全沒(méi)有任何關(guān)系。我們來(lái)專(zhuān)注這個(gè)屬性的本身,畢竟這個(gè)是標(biāo)題。
我很俗的查了一下MSDN
可以看出重點(diǎn)就是圖里指出的兩個(gè)機(jī)制:
1、客戶(hù)端瀏覽器的提交機(jī)制
2、ASP.NET 回發(fā)機(jī)制
解釋一下,有錯(cuò)誤的話(huà)請(qǐng)大家指正
1、大家可以看下這個(gè)鏈接所講的第一部分:http://www.th7.cn/Program/net/201309/150415.shtml
就是瀏覽器會(huì)封裝一個(gè)請(qǐng)求報(bào)文,發(fā)給服務(wù)器,服務(wù)器解析這個(gè)報(bào)文,進(jìn)行重組,生成一個(gè)響應(yīng)報(bào)文,回發(fā)給瀏覽器,瀏覽器收到后再對(duì)其進(jìn)行解析,就生成了我們看到的網(wǎng)頁(yè)和一些我們看不到的數(shù)據(jù)。它們之間的通信都是遵循HTTP協(xié)議。
重點(diǎn)強(qiáng)調(diào):HTTP是無(wú)狀態(tài)協(xié)議,也就是說(shuō)每次的瀏覽器請(qǐng)求,服務(wù)器響應(yīng)都是全新的一次。
2、大家可以看下這個(gè)鏈接所講的內(nèi)容:http://blog.sina.com.cn/s/blog_7815564501012qgy.html?? 對(duì)于回發(fā)機(jī)制,我希望大家能跟著這篇文章里講的步驟寫(xiě)個(gè)小Demo試試,會(huì)更有感覺(jué)。
回發(fā)機(jī)制,就是自己請(qǐng)求自己的頁(yè)面,這個(gè)機(jī)制比較搞,如果大家理解上一個(gè)機(jī)制,就會(huì)發(fā)現(xiàn)ASP.NET回發(fā)機(jī)制與其是有點(diǎn)背離的,上一個(gè)是無(wú)狀態(tài)的,這一個(gè)是能將前一次的值保存住,作為下一次頁(yè)面的初值。
舉個(gè)實(shí)際中的例子,就是當(dāng)我們?cè)谔顚?xiě)一個(gè)表單時(shí),有好多好多項(xiàng),但是當(dāng)我們填到倒數(shù)第二項(xiàng)的時(shí)候,不小心點(diǎn)擊了刷新,正常按第一個(gè)機(jī)制來(lái)說(shuō),表單內(nèi)控件上的值應(yīng)該全部被清空,因?yàn)榇藭r(shí)還沒(méi)有做數(shù)據(jù)庫(kù)讀取的操作,所以頁(yè)面不可能有值,但是有了回發(fā)機(jī)制,__viewstate把頁(yè)面保存了下來(lái),這樣就保留下了我們先前填寫(xiě)的內(nèi)容。不過(guò)技術(shù)群里的一個(gè)朋友說(shuō)“現(xiàn)在這個(gè)東西已經(jīng)很少會(huì)用了,基本不會(huì)用控件做項(xiàng)目開(kāi)發(fā)。”囧rz啊~我一直都用的不亦樂(lè)乎,怎么破?
兩個(gè)機(jī)制解釋完了,可能大家還是有點(diǎn)一頭霧水,其實(shí)此時(shí)我也是一樣。下面寫(xiě)個(gè)Demo讓整件事情變得更清晰點(diǎn)吧,借用一下Fiddler 這個(gè)工具。
頁(yè)面展示:
html代碼:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <html?xmlns="http://www.w3.org/1999/xhtml"> <head?runat="server"> ????<title></title> </head> <body> ????<form?id="form1"?runat="server"?method="post"> ????<div> ????????<asp:Label?ID="Label1"?runat="server"?Text="content:"?></asp:Label> ????????<asp:TextBox?ID="textbox_content"?runat="server"?width="500px"></asp:TextBox> ????????<asp:Button?ID="button_usesubmitbehavior_true"?runat="server"?Text="browser-server"? ????????????onclick="button_usesubmitbehavior_true_Click"?/> ????????<asp:Button?ID="button_usesubmitbehavior_false"?runat="server"?Text="postback"? ????????????UseSubmitBehavior="false"?onclick="button_usesubmitbehavior_false_Click"?/> ????</div> ????</form> </body> </html> |
頁(yè)面源碼:
后臺(tái)代碼:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ????public?partial?class?WebForm1?:?System.Web.UI.Page ????{ ????????protected?void?Page_Load(object?sender,?EventArgs?e) ????????{ ????????????textbox_content.Text?+=?"M"; ????????} ????????protected?void?button_usesubmitbehavior_true_Click(object?sender,?EventArgs?e) ????????{ ????????????textbox_content.Text?+=?"true"; ????????????button_usesubmitbehavior_true.Text?+=?"1"; ????????????button_usesubmitbehavior_false.Text?+=?"2"; ????????} ????????protected?void?button_usesubmitbehavior_false_Click(object?sender,?EventArgs?e) ????????{ ????????????textbox_content.Text?+=?"false"; ????????????button_usesubmitbehavior_true.Text?+=?"3"; ????????????button_usesubmitbehavior_false.Text?+=?"4"; ????????} ????} |
操作步驟:
1、初始頁(yè)面
2、先連續(xù)點(diǎn)擊browser-server按鈕三次
3、再連接點(diǎn)擊postback按鈕三次。
通過(guò)這個(gè)demo示例,如果單從頁(yè)面顯示上看,我們完全看不到兩者有什么不同,因?yàn)楹笈_(tái)想實(shí)現(xiàn)的功能兩者都實(shí)現(xiàn)了(就是點(diǎn)擊一下按鈕,會(huì)經(jīng)過(guò)一次page_load方法,然后再經(jīng)過(guò)各自的click事件,給文本框和兩個(gè)按鈕追加內(nèi)容)。但是利用fiddler工具,我們會(huì)發(fā)現(xiàn)提交的表單內(nèi)容的確是有些不一樣,UseSubmitBehavior屬性設(shè)為false的按鈕提交時(shí),本身沒(méi)有作為表單的參數(shù)傳遞給服務(wù)器端。
這就是唯一的不同嗎?感覺(jué)還是不夠,不過(guò)我真的是寫(xiě)不動(dòng)了。
有興趣的朋友可以再想想別的對(duì)比示例,比如試試在page上加EnableViewState="false"?這個(gè)屬性,看看點(diǎn)擊完按鈕會(huì)是什么效果的。這個(gè)我也有試,不過(guò)感覺(jué)還是不能證明什么。
啊,最后終于想到了一個(gè),你可以給browser-server按鈕加上EnableViewState="false"屬性,嗯嗯,這個(gè)比較靠譜,給browser-server 按鈕加上EnableViewState="false"屬性 ,目的就是讓其沒(méi)有回發(fā)機(jī)制,因?yàn)锳sp.Net控件默認(rèn)都會(huì)有回發(fā)機(jī)制,這樣browser-server 按鈕就只有單純的客戶(hù)端瀏覽器的提交機(jī)制,而postback按鈕就只有回發(fā)機(jī)制。頁(yè)面效果異常明顯啊~
賣(mài)個(gè)關(guān)子,想看效果的朋友自己去試一下吧,大家可以留言做交流,原諒我,這篇文章寫(xiě)的屬實(shí)有點(diǎn)累。
總結(jié)一下,UseSubmitBehavior?這個(gè)屬性絕對(duì)可以說(shuō)是非主流的,花時(shí)間去研究會(huì)不會(huì)很蛋疼?
其實(shí)最初根本沒(méi)有想過(guò)這篇文章會(huì)寫(xiě)這么長(zhǎng),但是隨著研究這個(gè)屬性深入,我去學(xué)習(xí)了ASP.NET的底層交互原理,ASP.NET頁(yè)面生命周期,回發(fā)機(jī)制以及了解了驗(yàn)證相關(guān)的問(wèn)題。說(shuō)實(shí)話(huà),收獲蠻多的,也很開(kāi)心。當(dāng)然,還要繼續(xù)實(shí)踐,學(xué)習(xí)。
附件:http://down.51cto.com/data/2364725
本文轉(zhuǎn)自 我不會(huì)抽煙 51CTO博客,原文鏈接:http://blog.51cto.com/zhouhongyu1989/1536727,如需轉(zhuǎn)載請(qǐng)自行聯(lián)系原作者
總結(jié)
以上是生活随笔為你收集整理的ASP.NET Button控件的UseSubmitBehavior属性引发的血案的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Yii框架特点及测试考虑
- 下一篇: 用asp.net还原与恢复sqlserv