ASP.NET MVC之初體驗

iDotNetSpace發表於2008-09-12

最近開始接觸ASP.NET MVC(以下簡稱MVC),已經是Preview 5版本了,估計正式版都快出來了,而很多資料還停留在Preview 3、4的程度,給我的學習造成一定困難。不過還好。

MVC給我的第一感覺就是思路清晰——通過URL來驅動,由於URL是可以包含語義的(事實上,我們在MVC中也是靠儘量讓URL擁有語義來幫助我們的),也就是說一個好的URL不僅可以讓它更好看——想想www.xxx.com/space.aspx?user=JimLiu還是www.xxx.com/space/JimLiu給人的感覺更好呢?而且這樣的URL可以讓我們開發者的思路更清晰——URL決定了業務。

這樣的話開發的時候會省事不少,最直接的表現就是原來我們經常通過在CodeBehind中用控制元件屬性或者Request[]來獲取資料,而現在我們可以直接通過Action方法的引數,比如一個Register方法,不僅可以把username, password傳入,甚至可以動態構建一個User物件傳入,這樣無疑是很方便的。雖然這裡還有很多問題,比如把驗證的壓力交給了客戶端等等,但我相信這種發展的趨勢是好的,微軟以後也肯定會改善。

同時還有省事的是在輸出資料的時候,我們就不再需要去費事地寫一個控制元件的OnDataBinding之類的事件,來控制它輸出的細節了,因為在MVC中輸出我們通常都用內聯服務端程式碼的方式來輸出了。有朋友覺得這樣做會退化到ASP那種邏輯程式碼和檢視混在一起的情況了,我覺得不然——我們所強調的是“業務邏輯”不應該和檢視混淆在一起,而在MVC中我們使用內聯服務端程式碼的方式來輸出HTML,並不是“業務邏輯”,而是“表現邏輯”,既然是表現邏輯,當然應該處於表現層了。而業務邏輯呢?當然是由Controller的Action方法來完成。

經過一段時間嘗試之後,我決定使用MVC框架重寫我們的Online Judge——原來是直接在Code Behind裡拼接SQL的、只求能用但是程式碼極其混亂的應用。雖然MVC給了我很大的便利,但是同時也帶來了不少麻煩。下面就談談我遇到的一些麻煩和對應的解決方案。

一、對於MasterPage中的業務邏輯,我沒有想到一種優雅的方式來解決,同時困擾我的還有一個Action中,如果需要要求頁面引用js, css檔案,或者註冊一個指令碼塊等,也不大方便。對於前一個問題,我目前還沒有好的辦法,有朋友提出使用ActionFilter來解決,我覺得不爽,因為ActionFilter是得作為Attribute來標記的,那這樣一來我如果在ActionFilter中處理母版頁的事情,不是得在用到這個母版頁的Action或者Controller上都標記個Attribute了?Attribute是什麼?是“特性”,而既然母版頁是“共性”,我覺得就不應該用Attribute來解決它。

後一個問題,我使用了一種很“齷齪” 的方法,就是往ViewData裡寫東西,比如我約定一個ViewData["Scripts"]是一個IList,然後我在母版頁裡foreach這個IList來註冊指令碼。

二、Authentication的問題。根據網上的資料,普遍解決Authentication的方法是用ActionFilter,我現在採用的也是這種方法。總的來說我還是覺得這樣實現是不錯的,但是還是有不爽的地方。

最突出的一點就是ReturnUrl了,我採用了兩個Action,一個是/Security/SignIn,一個/Security/SignOut,顯然,用於登入、登出,由於我需要ReturnUrl,所以我一定得在通向這兩個Action的表單/ActionLink中傳入這個ReturnUrl,這樣的要求是什麼?我在實現一個指向SignIn的表單的時候就必須給這表單的action帶上個ReturnUrl引數,指向現在的頁面,這還不算,我的MasterPage中有個ActionLink指向SignOut也得帶個QueryString了——不知為何這總讓我覺得不大自然,雖然我承認這無傷大雅。但我堅信在以後的版本中會有更健全的Authentication & Authoriation機制。

這裡還遇到另一個有趣的問題,那就是在我SignIn的時候,是存在成功不成功的,但是我需要做到的是:無論成功與否,都必須返回到ReturnUrl,但是根據不同的結果,再去給出一個提示,比如一個簡單地alert('登入失敗'),這就麻煩了點。我只能想到那個同樣“齷齪”的方法,就是往TempData的約定條目裡寫東西,然後還是在MasterPage裡判斷該給什麼提示。這樣做也太損了點,而且好像TempData是需要SessionState的,這點就很弱啊,因為為了效能我正考慮關閉SessionState呢,而且本來往Session裡寫東西就不是個好行為。不知道有沒有朋友有好的解決方案。

三、同一個頁面不同的訪問情況的問題。有時候我們的頁面是“全能” 的——表單提交之前,它這麼幹,表單提交之後,它那麼幹。如何優雅地解決這個問題呢?通過一個巨大的if{}else{}來判斷顯然不爽。經過搜尋我發現現在版本的MVC中已經有比較好的解決方案了,那就是.NET中的神奇的Attribute,對過載的Action方法,通過標記AcceptVerbs這個Attribute來確定哪個處理Post哪個處理Get,表單提交前我們顯然是在Get,提交之後嘛,就處理Post好啦,這就方便多了。

總的來說我覺得ASP.NET MVC還是一個很優秀的框架,可以幫助我們解決很多問題。我也相信在以後的版本中它會越來越好。對於上文中提出的幾個問題,希望有經驗和心得的朋友提供點指點。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-446858/,如需轉載,請註明出處,否則將追究法律責任。

相關文章