快速入門系列--MVC--05行為

來源:互聯網
上載者:User

標籤:快速   not   tps   desc   net   ror   決定   block   rip   

    Action執行包含內容比較多,主要有同步/非同步Action的概念和執行過程,Authorationfilter, ActionFiltor, ResultFilter, ExceptionFilter等四個主要過濾器類型的執行過程。首先介紹非同步Action,之前學習Controller的時候已經知道預設情況下Controller的執行是非同步,在不繼承非同步Controller的情況,我們代碼中的方法一般是同步的Action,我們可以通過使用Task<ActionResult>類型的傳回值和在Action方法使用Task.Factory.StartNew()等方法來調用非同步Action,主要用於I/O綁定等操作。ASP.NET是通過線程池的機制來處理並發的HTTP的請求的,這種方式的優點是:背景工作執行緒的重用,減少線程的建立和釋放;限制背景工作執行緒數量,避免高並發時伺服器的崩潰。這裡省略MVC4版本前的老式非同步Action調用,Task傳回值的Action如下所示:

 View Code

    在上代碼中,可以看到一個AsyncManager類,它起到了在非同步作業和回調操作間傳遞參數的作用。這是一個關於非同步作業很重要的類型,其屬性OutstandingOperatons是一個非同步作業計數器,類似訊號量的概念,用Increment設定初始值,當一個或多個非同步作業完成時遞減,為0時表示有所操作已完成,出發Completed事件,調用Finish方法。需要注意的細節是設定初始值的方法需要放在非同步作業的外部,非同步作業的逾時時間可以通過AsyncTimeoutAttribute特性的Duration屬性來設定。

接下來,介紹Action的執行過程,在Controller中,包括Model綁定和驗證在內的整個Action的執行是通過一個名為ActionInvoker的組件來完成的,也包含同步非同步兩個版本,實作類別為ControllerActionInvoker和AsyncControllerActionInvoker。這個簡單介紹一下Controller在選擇ActionInvoker時的步驟:通過DependencyResolver以IAsyncAcionInvoker查;以IActionInvoker查;建立非同步類型作為預設。不同的ControllerActionInvoker會建立其對應的ControllerDescriptor實作類別,包含對應類型的ActionDescriptor。還有一點需要注意的是,Dependency預設使用會將反射建立的對象緩衝到CurrentCache屬性中,而不會使用當前新設定的映射重新擷取。若想在程式中修改,需要手動的清空CurrentCache所對應類型中的_cache欄位,部分代碼如下所示:

 View Code

    在介紹篩選器的執行之前,再回顧一下相關過程,目標Action方法的最終執行是由被啟用Controller的ActionInvoker決定,ActionInvoker通過調用對應的ActionDesciptor來執行被它描述的Action。篩選器使用面向切面概念(AOP)的實現,它會在在Action方法執行的前後自動執行,主要包含非商務邏輯的實現,例如授權,異常處理等。Filter作為基類包含FilterScope和Order屬性,Scope包括First、Global、Controller、Action和Last,Order越小優先順序越高,預設值為-1。同樣Filter也有相應的Provider類,架構中原生的有FilterAttributeFilterProvider,ControllerInstanceFilterProvider和GlobalFilterCollection,簡介如下表所示:

類型 簡介
FilterAttribute, FilterAttributeFilterProvider 方法GetFilter得到的每個Filter,對應的FilterAttribute特性作為其Instance屬性,Scope屬性取決於FilterAttribute特性是應用在Controller類型上還是Action方法上。
Controller, ControllerInstanceFilterProvider Controller實現了IActionFilter,IAuthorization等四介面,本身就是一個篩選器,通過ControllerInstanceFilterProvider類型來表示針對Controller對象這種特殊篩選器的Filter。它的GetFilter方法根據ControllerContext獲得對應Controller,並作為Filter的Instance屬性,其Scope為First,Order為Int32.MinValue,預設最先執行。
GlobalFilterCollection 全域的Filter通過GlobalFilter.Filters.Add方式來添加,預設Scope為Global。

    在篩選器的執行順序上,遵循先Order排序,再Scope排序,若同一篩選器特性標註在不同Scope上且AllowMultiple為false時,會選中最後的一個執行。架構使用一個FilterInfo類型統一管理內建的篩選器,之後開始按照執行順序詳細介紹各個內建的篩選器。

 

AuthorizationFilter,實現IAuthorizationFilter的OnAuthoration方法用於實現授權操作,成功後繼續Action後續工作(Model綁定,驗證,Action的執行),失敗後AuthorizationContext對象的Result屬性回複一個"401,Unauthorized"相應或者重新導向到錯誤頁面。它所對應的幾個實現IAuthorizationFilter介面的如下表所示:

類型 簡述與例子
AuthrizeAttribute 多個Authorize特性間是"邏輯與"得關係,如下代碼任何使用者均無法訪問。[Authorize(Users = "Xixi", Roles="Admin")] [Authorize(Users = "XiongEr", Roles = "Admin")] public void CannotCall() { }
RequiredHttpsAttribute 要求請求為HTTPS形式(HttpRequest.IsSecureConnection),不滿足時,如果是GET方式請求返回RedirectResult重新導向請求,如果是其他方式拋出異常。
ValidateInputAttribute 在Controller, Action層級上針對整個請求決定輸入參數是否進行驗證。例如在QueryString中放入"<script></script>"
ValidateAntiForgeryTokenAttribute 防止CSRF(Cross-Site Request Forgery)跨站請求偽造網路攻擊,如果說XSS(Cross Site Script)是利用了使用者對網站的信任,那個CSRF就是利用了網站對認證使用者的信任。在之後的內容中,將繼續介紹CSRF的原理和架構的預防方法。
ChildActionOnlyAttribute 一般用於產生組成頁面的某部分HTML,若非子Action則拋出異常。(通過DataTokens中是否包含ParentActionViewContext判斷)

    接下來用蔣老師介紹的簡單例子來解釋CSRF的原理,假設我們獎勵一個部落格應用,作為博主的我們可以發表博文,而一般使用者(包括匿名)可以評論。除此之外註冊使用者可以修改自己的綁定Email,我們將授權特性加在該Action上,看起來應該OK了,但仍然有漏洞可鑽。

    從可知,通過跳轉攻擊者獲得使用者安全性權杖,通過了授權驗證,說明CSRF是一種隱蔽且危害巨大的攻擊,架構通過ValidateAntiForgeryTokenAttribute結合HtmlHelper的AntiForgeryToken方法有效解決了這個問題。在View中通過調用AntiForgeryToken方法,在頁面中生一個值為防偽令牌字串的hidden類型的<input>元素,並且設定一個具有HttpOnly的Cookie。防偽令牌值通過Salt,Creation,Username等內容計算得出。Cookie的名稱通過應用路徑base64編碼值加上_RequestVerificationToken組合而成。對於加入防偽令牌的View在第一次訪問或者Cookie不存在時,建立Cookie並設定HttpOnly標籤,這樣瀏覽器就無法通過指令碼獲得Cookie,保證了Cookie的安全。再次請求時,解密和還原序列化Hidden與Cookie中相關值,比較屬性即可。

 

ActionFilter之前介紹過的實作類別包括AsyncTimeoutAttribute等,允許我們對Action執行前後添加一些額外操作,通過Result屬性響應其請求。篩選器中OnActionExecuting與OnActionExecuted的執行順序相反。正向執行時,一旦某一個ActionFilter將AcionExecuteingContext的Result設定為ActionResult對象,後續ActionFilter和目標Action將不會執行。而在逆向執行ActionFilter鏈時在ActionExecutedContext中設定Result不受影響,如所示:

    ActionFilter鏈的異常處理過程通過對應的上下文類的Exception對象傳遞,ExceptionHanlded屬性工作表明異常是否已被處理。

ExceptionFilter既可以處理ActionFilter最終拋出的異常,還可以處理ResultFilter拋出的異常。其中實作類別HanldeErrorAttribute用於針對具體的異常類型來呈現對應的錯誤頁面。同時由於ExceptionFilter鏈的反向執行特性,需要設定Order屬性使得具體的HanldeErrorAttribute優先執行。

    需要注意的一點是,HandleErrorAttribute只有在允許自訂錯誤時才有效, <customErrors mode="On"/>

蔣老師在書中提到,異常處理是程式員最熟悉也最難掌握的一塊概念了,我確實也有這樣的感受,比如說一個異常類型到底"誰來管,該怎麼管,管不住怎麼辦",很像法制建設,需要一定的規定,但軟體開發中還未有相關的通用規則。由於異常處理往往是情境驅動的,就需要一個靈活可配置的處理架構進行管理,例如微軟企業庫Entlib的Exception Handling Application Block(EHAB)。該庫提供一種基於"策略"的異常處理方式。之後還提供了一個自動化處理異常的思路,即通過配置,自動產生try/catch過程。

簡單來說就是:

異常處理策略=異常類型+異常處理器+異常後續處理方式,例子如下所示:

 View Code

相應的調用方式為:

 View Code

ResultFilter用於控制ActionResult的執行,屬於在Action方法執行過後對ActionResult執行過程的控制,也就是對視圖渲染的控制了,內容與ActionFilter相似,就不介紹了。

 

註:本文主要供自己學習,不妥之處望見諒。

參考資料:

[1]蔣金楠. ASP.NET MVC4架構揭秘[M]. 上海:電子工業出版社, 2012. 320-389

快速入門系列--MVC--05行為

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.