ASP.NET MVC中(zhōng)你必須知道的13個(gè)擴展點
ScottGu在其最新的博文中推薦了Simone Chiaretta的(de)文章13 ASP.NET MVC extensibility points you have to know,該文(wén)章為我(wǒ)們簡單介(jiè)紹了ASP.NET MVC中的13個(gè)擴展點。Keyvan Nayyeri(與Simone合著了Beginning ASP.NET MVC 1.0一書(shū))又陸(lù)續(xù)發表了一些(xiē)文章,對(duì)這13個擴展點(diǎn)分別進行深(shēn)入的討論。我將在以後的隨筆中對這些文章逐一進行翻譯,希望能對大家有所幫助。
ASP.NET MVC設計的主要原則之(zhī)一(yī)是可擴展性(xìng)。處理管線(processing pipeline)上的所有(或(huò)大(dà)多數(shù))東西都是可替換的。因此,如(rú)果您不(bú)喜歡ASP.NET MVC所使用的(de)約定(或缺乏某(mǒu)些約定),您可(kě)以創建自己的服務(wù)來支持您的約定,並將其(qí)注入到主管線中。
在本文中,我們將從管線開始(shǐ)直到視圖呈現,逐一(yī)向您展示(shì)每個ASP.NET MVC開(kāi)發者都必須了解(jiě)13個(gè)擴展點。
1.RouteConstraint
通常情況下你可以使用正則表達(dá)式對url參數進(jìn)行約束(shù),但如(rú)果您的約束不僅僅取決於單一參數,您可以實(shí)現IRouteConstrains的(de)方法(fǎ),並在其中添加你的驗證邏輯。
比如對日期的驗證,url中可能會包含年(nián)、月、日(rì),而(ér)你需要驗證這三(sān)者是否可以組合成一個有效(xiào)的日(rì)期(qī)。
2.RouteHandler
RouteHandler是在(zài)路由選擇之後進行處理(lǐ)的組件,它並不僅僅針(zhēn)對ASP.NET MVC。顯然,如果您改(gǎi)變了(le)RouteHandler,那麽對請求(qiú)的處理將不再使用ASP.NET MVC,但(dàn)這在您使用其他HttpHandler或經典的WebForm進行路由(yóu)處理(lǐ)時卻(què)是非常有(yǒu)用的。
3.ControllerFactory
ControllerFactory是基於路由(yóu)的組件(jiàn),它選擇(zé)正確的(de)controller並對其實例化(huà)。default factory會查找實現了IController並且以Controller結尾的類,然後通(tōng)過反射使用無參構造函(hán)數進(jìn)行實例化。
但如果您希望使用依賴注入,就(jiù)不能再(zài)使(shǐ)用default factory,而必須使用支持IoC的controller factory。MvcContrib和Ninject Controller Factory都包含支(zhī)持(chí)IoC容器(qì)的controller factory。
4.ActionInvoker
ActionInvoker顧名思義(yì)是負責調用(invoke)action的。默認的action invoker通過方法名、action名或其(qí)他(tā)可能的selector attribute來(lái)查找action,然後調用action方法以及(jí)定義的(de)filter,最終執行得到action result。
你會發現大部分執行管(guǎn)線存(cún)在於ControllerActionInvoker類的邏輯之中。因此,如果希望改變這些約(yuē)定,如action方(fāng)法的選(xuǎn)擇(zé)邏輯(jí)、http參數映射(shè)到action參數的方(fāng)式、選(xuǎn)擇和執行filter的方式等,您需要擴展該類並重寫需要修改的方法。
可(kě)以(yǐ)參閱NinjectActionInvoker I developed to allow injection of dependencies inside filters。
5.ActionMethodSelectorAttribute
使用默認的action invoker時,action的選擇是基於名稱的。您(nín)也可以實現自己(jǐ)的Method Selector以改善對於action的選擇。在框架中已經(jīng)包含了AcceptVerbs特性,它允(yǔn)許您指定使用哪一(yī)個HTTP Verb來處理action的響應。
例(lì)如(rú),您也許會希(xī)望基於瀏覽器所支(zhī)持的(de)語言(yán)或瀏覽器類型(如移動(dòng)設備的瀏覽器或(huò)桌(zhuō)麵瀏覽(lǎn)器)來進行action的選取。
6.AuthorizationFilter
這種過濾器是在action執行之(zhī)前執行的(de),用來確保請求是有效(xiào)的。
框架中已(yǐ)經包含(hán)了(le)一些(xiē)autorization過濾(lǜ)器(qì),最有名的(de)莫(mò)過(guò)於Authorize特性,它用來檢查當(dāng)前用戶是否允許執行(háng)該(gāi)action。另一個是(shì)用來阻止CSRF攻擊的ValidateAntiForgeryToken。如果您希(xī)望實現自己的authorization,那麽必須(xū)實現接口。例如(rú),日期(qī)中的小時。
7.ActionFilter
Action Filters在action執行前後執行。OutputCache過濾器(qì)是幾個核(hé)心過(guò)濾器之一。這(zhè)可能是您最有可能使用的擴展點,並且在我(wǒ)看來,controller隻關心它的主要工作,而view所需(xū)要的所有其(qí)他數據都必須從action過濾(lǜ)器內部獲取,這樣的實現對於一個組織良好的view來說,是(shì)十分關(guān)鍵(jiàn)的。
8.ModelBinder
默(mò)認的model binder使(shǐ)用參數名稱進(jìn)行HTTP參數到action方(fāng)法參數的映射。例如(rú),http參數user.address.city將映射(shè)到方法(fǎ)參(cān)數user的Address屬性的City屬性。DefaultModelBinder也(yě)同(tóng)樣適(shì)用於數組和(hé)其他列表類型(xíng)。
更(gèng)進一步來說,例如,您可能希望從數據庫中進行檢索,直(zhí)接根(gēn)據person的id將其轉換為(wéi)Person對象。Timothy Khouri(網名(míng)SingingEels)在他的文章Model Binders in ASP.NET MVC中更好的闡述了這(zhè)種方法。他(tā)的(de)代(dài)碼基(jī)於Preview 5,但其理(lǐ)念是一樣的。
9.ControllerBase
所有的Controller均繼(jì)承自基類Controller。要想在action中封(fēng)裝自己的邏輯和(hé)約定,創(chuàng)建(jiàn)自己的父類使所有Controller繼承自(zì)該類,是(shì)一種很好的方式。
10.ResultFilter
與ActionFilter類似,ResultFilters在ActionResult前後執行。OutputCache過濾器也可以作為ResultFilter的(de)示例。另外,比較常用(yòng)的詮釋(shì)這種過(guò)濾器的示例(lì)是日誌記錄。如(rú)果(guǒ)您希望在頁麵返回給(gěi)用戶時記錄日誌(zhì),可以編(biān)寫自(zì)定義的(de)RenderFilter,在ActionResult執行之後(hòu)記錄日(rì)誌。
11.ActionResult
ASP.NET MVC提供了很多result用(yòng)來呈現視圖、JSON、純文本、文件並重定向到其他action。如果您需要其他類型的result,可以自定義(yì)ActionResult,並實現ExecuteResult方法。例如,如果您(nín)希望(wàng)將PDF文件作為結果發送,您(nín)需要使用PDF庫(kù)編(biān)寫能夠生成PDF的(de)ActionResult。又如RSS feed,可參見how to write a RssResult in this post。
12.ViewEngine
您可能不需要編寫自己(jǐ)的(de)view engine,但您也許可以考慮使用其他引(yǐn)擎來替代默(mò)認的WebForm view engine。在我看來,最有(yǒu)趣的引擎就(jiù)是Spark。
如果您確實希(xī)望編寫自己(jǐ)的view engine,可以看(kàn)一下(xià)Brad Wilson的(de)文章: Partial Rendering & View Engines in ASP.NET MVC。
13.HtmlHelper
視(shì)圖必須十分簡(jiǎn)單整潔,它們隻能包含html標(biāo)記並(bìng)調用(yòng)HtmlHelper的輔(fǔ)助方法。視圖中不(bú)能包含任何(hé)代碼(mǎ),所以輔助方(fāng)法必須十分(fèn)方便(biàn),使(shǐ)您(nín)可以將代碼從視圖中(zhōng)提(tí)取(qǔ)出來,放到一個(gè)可測試的環境中去。正如Rob Conery所說:如果有if,就構造輔助方法(If there's an IF, make a Helper)。
什麽(me)是HtmlHelper輔(fǔ)助(zhù)方法?其實就是HtmlHelper類(lèi)的擴展方法,這是唯一的要求。
你可以從Rob的文(wén)章(zhāng)Avoiding Tag Soup中了解到為什麽(me)說HtmlHelper是封裝(zhuāng)視(shì)圖中(zhōng)代碼(mǎ)的好方法。
在您的應用中該使用哪個呢(ne)?
正如您所猜測的那樣,並不是所有的應用都(dōu)需要擴展以上的13個擴展點(diǎn)。最可能(néng)在所有應用中進行擴(kuò)展(zhǎn)的是ActionFilter和HtmlHelper。另外,您很(hěn)可能(néng)會使用其他人編寫的擴(kuò)展,如使用了IoC容器的ControllerFactory或用(yòng)來(lái)擺(bǎi)脫WebForm的ViewEngine。
但是,學習(xí)這(zhè)些擴展點並進行嚐試是十分重要的,這樣您才會做出選擇,並隨時準備在必要(yào)的時候使用這些強(qiáng)大的擴展(zhǎn)點。下周我(wǒ)將發表(biǎo)一些文(wén)章(zhāng)來闡述如何使用這些擴展點。
如(rú)果您想詳細了解(jiě)更(gèng)多(duō)關於該(gāi)話題的內容,可以考(kǎo)慮購買即將出版的Beginning ASP.NET MVC(我是作(zuò)者之一)或(huò)Professional ASP.NET MVC(ASP.NET MVC開發(fā)團隊編寫(xiě))或ASP.NET MVC in Action (Jeffrey Palermo和Ben Scheirman著)。
我是否遺漏了某些您認(rèn)為重要的(de)擴展(zhǎn)點呢?您是否使用過我(wǒ)上麵提到(dào)的擴展點(diǎn)呢?我很想聽聽您所遇(yù)到的場(chǎng)景。
關(guān)鍵詞:ASP.NET
閱(yuè)讀本文後(hòu)您有(yǒu)什麽感想? 已有 人給出(chū)評價!
- 1
- 2
- 2
- 1
- 1
- 1