這兩天同事寫的ASP.Net網頁元件有一種怪異的現像發生…
現像如何?待我說來吧~
主角:同事開發的custom control元件,此處稱為「A君」
某同事放的一個web control--LinkButton,此處稱為「LB君」
來插花的使用者,此處稱為「路人甲」
主角行為描述:LB君在server side有一個method是其Click事件的delegation,
此事件會執行一行程式碼『Response.Redirect("TextFile1.zip");』,
此動作會讓前端的路人甲看到檔案下載確認視窗。
A君看起來是一個網頁上的Button,他的client side script event:onclick被觸發後
(就是A君被點了一下之後)會執行『Form_name.submit();』,用來將所在的form送出。
路人甲就是什麼都不知道,只想按按看按鍵的天神user。
劇情:路人甲他要先按了LB君下載完檔案之後再點一下A君做其他事。
當路人甲按了LB君之後正常跳出下載檔案對話窗,接著路人甲下載完檔案後便點了A君一下,
這時神奇的事發生了,剛剛出現過的下載檔案對話窗又出現了!
路人甲便在覺得莫明其妙的狀況下又下載了一次檔案…
發現問題:經過一陣兵荒馬亂的debug之後發現問題完全不在server side…
其實一切的一切都很合理,也完全沒有靈異現像,至於為什麼會發生這樣的結果,
我們要從ASP.Net的事件觸發方式開始討論起。
寫過以前的ASP或JSP或有其他任何動態網頁程式開發經驗的人都瞭解,
server side是不可能無端端知道client side的使用者剛剛按了那個按扭,
或是那個DropDownList剛被更動過。
那為什麼ASP.Net的網頁可以讓程式設計師像寫WinForm程式一樣產生UI上control所觸發的事件呢?
重點就在於client side的一支名叫,『__doPostBack(eventTarget, eventArgument)』
的script function,這支function做的事很簡單但卻很重要,它的程式碼如下:
===============================================================================
function __doPostBack(eventTarget, eventArgument) {
var theform;
if (window.navigator.appName.toLowerCase().indexOf("netscape") > -1) {
theform = document.forms["Form1"];
}
else {
theform = document.Form1;
}
theform.__EVENTTARGET.value = eventTarget.split("$").join(":");
theform.__EVENTARGUMENT.value = eventArgument;
theform.submit();
}
===============================================================================
這支function就是負責將client side觸發事件control(可能是button或是dropdownlist甚或是textbox)
的id和它要傳送的event由__EVENTTARGET和__EVENTARGUMENT這兩個隱藏欄位送到server side,
server side在收到form的request之後便會依這兩個欄位的值來決定server side要執行那個method。
所以之前路人甲點了LB君之後再點A君會發生LB君的事件被再次觸發就有了合理的解釋,
在路人甲點了LB君之後,LB君會以__doPostBack('LB君','');的方式將訊息送到server side,
此時__doPostBack()會把__EVENTTARGET.value的值設為'LB君',
server在看到這段之後就去找到LB君在server side的delegation,進而達成他應該達成的任務。
之後路人甲又點了A君,因為A君是單純的以client script呼叫Form_name.submit(),
因此剛剛已經被設了值的__EVENTTARGET.value還是保留著剛剛被__doPostBack()更改過的值,
因此server side還是以為這次呼叫的也是LB君,因此還是盡責的把該做的事再做一次。
解決方案:知道了前因後果後,要解決這個問題就簡單多了。
其實我們要做的就是把A君在client side的動作由Form_name.submit()
改成呼叫__doPostBack('A君','')就可以了,又或著可以在呼叫Form_name.submit()前先把
__EVENTTARGET和__EVENTARGUMENT兩個隱藏欄位的value清空就可以了。
後記:ASP.Net讓web開發作業變的更簡單輕鬆,但卻也在程式的背後做了更多我們沒看到的事。
所以發生問題時我們必需要更細心的去尋找其所以然,否則便常常會發生所謂的靈異事件了。
2005-07-22
ASP.Net 中 Form_name.submit() 的靈異現像~
Posted by 瓶子 at 7/22/2005 10:57:00 AM
Labels: Computer - Programming
Subscribe to:
Post Comments (Atom)
1 comment:
Non si svuotò a causa della vecchiaia
Qualcuno si è unito mentre faceva un pompino a suo marito
Ha un chip in testa e ha il controllo.
Goduto il fresco verso il mare
Ha fatto il suo uccello tatuato
Mette il cuscino in una posizione comoda
Porno italiano in alta definizione gratis
Bionda scopa la moglie dal culo
Cazzo il suo ragazzo e la matrigna
Donna bruna che lavorava precedentemente nel team di Brazzers
Post a Comment