国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

利用多態(tài),實(shí)現(xiàn)一般處理程序(ashx)中的AOP(切面編程)

2019-11-14 14:23:45
字體:
供稿:網(wǎng)友

本文是對工作中的項(xiàng)目進(jìn)行代碼優(yōu)化(完善登陸驗(yàn)證的AOP切面編程)時(shí),所遇到的各種解決方案思考過程。

項(xiàng)目背景:由ashx+nvelocity構(gòu)建的簡單B/S問卷系統(tǒng),現(xiàn)需要優(yōu)化登錄驗(yàn)證環(huán)節(jié)(時(shí)隔若干個(gè)月在回顧代碼果然是一個(gè)痛苦的過程~)

nvelocity是velocity框架針對.net的版本,核心是拼html字符串后返回客戶端,與MVC的前后端代碼隔離有異曲同工之妙。加之一般處理程序ashx不需要像asp.net那樣走生成控件樹的過程,執(zhí)行上更是省時(shí)省力。故簡單系統(tǒng)用ashx+nvelocity的形式構(gòu)建筆者個(gè)人還是比較推薦的。如果那么在意訪問地址(如www.abc.com/news/index.ashx?id=234)中的ashx后綴不好看,完全可以通過模塊(HttpModule)來實(shí)現(xiàn)url重寫。

本文討論的是:如何在ashx中體現(xiàn)AOP切面編程思想?

(1)回顧asp.net,所有頁面繼承自Page類,可通過Page的子類來實(shí)現(xiàn)AOP。原來是:Default : Page,切面插入后是:Default : LoginCheckPage,LoginCheckPage : Page。如此便能在LoginCheckPage類中編寫登錄驗(yàn)證的代碼,且能實(shí)現(xiàn)所有需要驗(yàn)證頁面的有效解耦——解耦是相對于專門寫一個(gè)LoginCheck類,并在各個(gè)Default頁面做驗(yàn)證(如LoginCheck.Check(context))而言,更利于修改與拓展。

(2)回顧MVC,可以依樣畫葫蘆像上述asp.net那樣,原來是:HomeController:Controller,切面插入后是:HomeController:LoginCheckController,LoginCheckController:Controller。除此之外,還能利用類/方法頭上的特性標(biāo)簽來做AOP。

在asp.net與MVC中的AOP體現(xiàn)還有許多做法,此處拋磚引玉、僅為比對ashx的AOP做思考:上述方法在ashx中能行得通嗎? 能!但要做些微調(diào):

(獨(dú)寫一個(gè)LoginCheck類,然后在每個(gè)需要驗(yàn)證的ashx.PR()中加上LoginCheck.Check(context)實(shí)在不是長久之計(jì),故本文就不另說了)

第一種嘗試:(沒錯(cuò),本文最后一次才嘗試成功,不過寫出嘗試過程也是為了將自己所走的彎路做下記錄,且希望能給讀者更多思考的提示,感謝堅(jiān)持讀完三種嘗試的朋友。)

利用HttpModule。類似url重寫那樣,url重寫不都是每次請求一來就做處理嗎,那Module應(yīng)該也能做登陸吧——兩者差異:普通的url重寫不涉及客戶端隔離、不考慮請求的資源,登錄驗(yàn)證要做客戶端隔離(cookie)、要考慮請求的資源(并不是所有資源都不給訪問,有的是游客級別就行的)。

對于要考慮請求資源的差異,如果惡心一點(diǎn),可以在代碼中寫死(可優(yōu)化成在webcofig、其他配置文件、數(shù)據(jù)庫存儲(chǔ))來做差異化處理——以正則表達(dá)式匹配請求地址,用來隔離需要驗(yàn)證登陸的請求與不需要驗(yàn)證的請求。

對于客戶端隔離,能否直接在Module中用session?首先要使HttpModule繼承自IReadonlySessionState/IRequiresSessionState接口(HttpHandler也是如此),以便在走管道的時(shí)候能被.net認(rèn)出來你這個(gè)Module想用session。注冊到BeginRequest事件。別忘了還要注冊到webconfig。一切就緒,調(diào)試,報(bào)錯(cuò)——Httpapplication中的Session屬性報(bào)錯(cuò),未將對象引用設(shè)置到對象實(shí)例。是不是注冊的事件錯(cuò)了?我查了一遍HttpApplication管道中的19個(gè)事件,最佳的切入點(diǎn)在第10-11個(gè)事件之間,也就是+=PostAcquireRequest,才能在獲取Session之后、在執(zhí)行ashx之前做登陸驗(yàn)證。

然而并沒有什么X用……依舊未將對象引用設(shè)置到對象實(shí)例。怎么還是沒有呢,奇了怪了。

又是一邊各種查,查到一句話說得好:Module是應(yīng)用程序級的事兒,是過濾作用,而Session是頁面級的事兒,是要根據(jù)發(fā)來的請求做不同的處理,故在Module中用Session本就不是最佳方案。故放棄Module這條彎路。

第二種嘗試:

自定義繼承自IHttpHandler的ashx。原來:Index:IHttpHandler,優(yōu)化后:Index:LoginCheckHandler,LoginCheckHandler:IHttpHandler。學(xué)的上述asp.net與mvc中的插入到繼承樹的方法。但調(diào)試結(jié)果是根本不走Index的ProcessRequest(),直接走完LoginCheckHandler.ProcessRequest()就返回了,客戶端就是空白一片。究其原因:實(shí)現(xiàn)IHttpHandler的一般處理程序(無論是Index,還是LoginCheckHandler),都只會(huì)執(zhí)行一次ProcessRequest()。

第三種嘗試:

在第二種的基礎(chǔ)上修改為:LoginCheckHandler中的ProcessRequest()改為virtual,并在Index子類中override重寫,并在Index.ProcessRequest()中調(diào)用base.ProcessRequest(context)。執(zhí)行的時(shí)候,程序會(huì)因?yàn)榭吹給verride而忽略父類的PR方法,而Index子類中的base.PR()又要求程序先走父類的PR方法,且結(jié)合Response.Redirect()的立即輸出特性(先Flush,在End),可以使得不滿足登錄驗(yàn)證條件的請求被擋在門外。小功告成!

麻煩的是,要修改子類為override,且在子類中存在base.PR()代碼(也只比簡單粗暴的調(diào)用LoginCheck.Check(context)來驗(yàn)證減少了一些些耦合度),那么還有更好的AOP方法嗎?望各位大牛看官提點(diǎn)。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 安远县| 万源市| 内黄县| 梨树县| 苏尼特右旗| 铅山县| 常宁市| 阿图什市| 夏河县| 涡阳县| 从化市| 陵川县| 临朐县| 昆明市| 绍兴市| 永定县| 郸城县| 保康县| 金乡县| 儋州市| 贺兰县| 漳平市| 三门峡市| 玛曲县| 苗栗县| 桦南县| 海南省| 南京市| 兰溪市| 玛纳斯县| 仁怀市| 威海市| 松溪县| 德惠市| 女性| 驻马店市| 原平市| 利川市| 肃宁县| 遵义县| 开化县|