2005-07-22

ASP.Net 中 Form_name.submit() 的靈異現像~

這兩天同事寫的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-14

很多人都有經歷過的一段故事~

從橘子那邊看到立子異言堂裡的一段故事,裡面說的是異言堂副堂主卜仔的愛情史

平順的陳述文字中,讓人看到了一種堅持和感動。說實在的,要看天搖地動般的愛情詩篇的話,還是建議去看看瓊瑤婆婆的死去活來系列比較好,卜仔的愛情故事裡面沒有那種撕裂心肺的痛和約定來生的誓言,但為啥還是有感動的感覺?我想是因為其在現實中的誠肯吧…

如果看完之後你覺得沒什麼,覺得不知道我在說什麼…
那可能我該恭喜你,看來你的感情生活順遂…
又或著我該替你感到惋惜,看來你已失去那最初的純真…

看完後別忘了,參與一下卜仔的行動吧~

展開全文...

2005-04-19

多年好友…

那天跟這位老兄算了一算,到2005年為止,我們已經認識超過12年了~
想想還直是不算短的時間。

雖然高中畢業之後各自都經歷了不少的事情,但大家一見面還是跟以往一樣,感覺有一種無法割捨的友誼…Posted by Hello

展開全文...

還沒搞清楚要怎麼玩 =.="

基本上我比較喜歡這個BLOG的管理和界面風格,因為它比較傳統也比較沒那麼“微軟”…

但它的登入方式及界面編輯的部份當然是完全無法跟MSN的BLOG(我想微軟應該還是比較喜歡叫它做“分享空間”,但甘我屁事…)相比的…

而且…
到目前為止小弟我還沒找到它放圖片的地方~~:P
一方面是因為界面不夠直接,一方面是因為沒有花心細好好找一下~~XD

所以呢~~
有來逛到的人就先忍忍吧,等我把它摸熟了再來好好大搞一番~~^__^

p.s. 其實之前裝過一套“Movable Type”,但無耐家中的主機實在不想24小時一直開著,所以就正式關站啦,否則那套是不錯用滴,介紹給想自己架BLOG的人玩玩~~^____^

展開全文...

2005-03-09

開場白

新的blog,新的希望~

展開全文...