<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      ASP.NET MVC中的ActionFilter是如何執行的?

      在ASP.NET MVC中的四大篩選器(Filter),ActionFilter直接應用在某個Action方法上,它在目標Action方法執行前后對調用進行攔截以執行一些額外的操作。這是一種典型的AOP式的設計,如果我們需要在執行某個Action方法的前后執行一些操作,可以通過定義ActionFilter來實現。本篇文章主要講述多一個應用到相同Action方法上的ActionFilter的執行機制。[本文已經同步到《How ASP.NET MVC Works?》中]

      目錄
      一、ActionFilter
      二、ActionFilter的執行機制
      三、ActionFilter對ActionResult的設置
      四、ActionFilter中的異常處理

      一、ActionFilter

      ActionFilter允許我們在目標Action方法執行前后對調用進行攔截以執行一些額外的操作,所有的ActionFilter實現了具有如下定義的接口IActionFilter

         1: public interface IActionFilter
         2: {    
         3:     void OnActionExecuting(ActionExecutingContext filterContext);
         4:     void OnActionExecuted(ActionExecutedContext filterContext);
         5: }
         6:  
         7: public class ActionExecutingContext : ControllerContext
         8: {    
         9:     public ActionExecutingContext();
        10:     public ActionExecutingContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> actionParameters);
        11:     
        12:     public virtual ActionDescriptor            ActionDescriptor { get; set; }
        13:     public virtual IDictionary<string, object> ActionParameters { get; set; }
        14:     public ActionResult                        Result { get; set; }
        15: }
        16:  
        17: public class ActionExecutedContext : ControllerContext
        18: {    
        19:     public ActionExecutedContext();   
        20:     public ActionExecutedContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor, bool canceled, Exception exception);
        21:     
        22:     public virtual ActionDescriptor     ActionDescriptor { get; set; }
        23:     public virtual bool                 Canceled { get; set; }
        24:     public virtual Exception            Exception { get; set; }
        25:     public bool                         ExceptionHandled { get; set; }
        26:     public ActionResult                 Result { get; set; }
        27: }

      如上面的代碼片斷所示,IActionFilter接口中定義了兩個方法OnActionExecuting和OnActionExecuted,這兩個方法分別在目標Action方法執行前后被調用,它們的參數類型分別為ActionExecutingContextActionExecutedContext。這兩個上下文了類型均是ControllerContext的子類。

      我們可以從ActionExecutingContext對象中獲取到用于描述當前Action的ActionDescriptor,以及參數列表。ActionFilter可以在OnActionExecuting方法中對ActionExecutingContext對象的Result屬性進行賦值來直接響應當前的請求。一旦ActionExecutingContext的Result屬性被成功賦值,將會終止后續ActionFilter和最終目標方法的執行。

      ActionExecutedContext具有額外的三個屬性,Exception表示執行Action方法過程中拋出的異常,而ExceptionHandled是一個表示是否對異常已經做出處理的標記。Canceled屬性表示沒有完成整個ActionFilter鏈和目標Action方法的執行而中途被終止。

      二、ActionFilter的執行機制

      image當ActionInvoker在執行目標Action方法之前,會根據Order和Scope屬性對用于封裝ActionFilter的Filter對象進行排序。然后根據當前ControllerContext和ActionDescriptro創建一個ActionExecutingContext對象,并將其作為參數依次調用所有ActionFilter的OnActionExecuting方法。

      在這之后真正的目標Action方法被執行,ActionInvoker隨后執行后續的篩選操作。具體來說,它根據當前ControllerContext、ActionDescriptro以及Action方法執行過程中拋出的異常創建一個ActionExecutedContext對象。該ActionExecutedContext的Cancel屬性為False,如果Action方法返回一個ActionResult對象,該對象將會作為該ActionExecutedContext的Result屬性。

      接下來按照相反的次序依次調用ActionFilter對象的OnActionExecuted方法,執行過程中的ActionFilter可以修改ActionExecutedContext的Result屬性。當整個ActionFilter鏈執行結束之后,ActionExecutedContext的Result屬性返回的ActionResult將會作為對當前請求的響應。右圖基本上反映了連同目標Action在內的整個ActionFilter鏈的執行過程。

      三、ActionFilter對ActionResult的設置

      上面我們已經提到過,在ActionFilter鏈進行OnActionExecuting方法調用的過程中,一旦某個ActionFilter為ActionExecutingContext的Result屬性設置了一個ActionResult對象,后續ActionFilter和目標Action將不會被執行。實際上此時ActionInvoker此時會創建一個ActionExecutedContext對象,設置的ActionResult直接作為其Result屬性,而Cancel屬性被設置為True。我們現在考慮的問題是:之前的ActionFilter的OnActionExecuted是否還被執行呢?

      為了弄清楚這個問題,我們來創建一個測試程序。在通過Visual Studio的ASP.NET MVC項目模板創建的空Web應用中我們定義了如下三個ActionFilter(FooAttribute、BarAttribute和BazAttribute),它們都繼承自我們自定義的FilterBaseAttribute。在FilterBaseAttribute中實現的OnActionExecuting和OnActionExecuted方法中,我們將ActionFilter自身的類型和執行方法名寫入當前HttpResponse并最終呈現在瀏覽器中。BarAttribute重寫了OnActionExecuting方法,在調用基類同名方法之后為ActionExecutingContext的Result設置了一個EmptyResult對象。

         1: public abstract class FilterBaseAttribute : FilterAttribute, IActionFilter
         2: {
         3:     public virtual void OnActionExecuted(ActionExecutedContext filterContext)
         4:     {
         5:         filterContext.HttpContext.Response.Write(string.Format("{0}.OnActionExecuted()<br/>", this.GetType().Name));
         6:     }
         7:  
         8:     public virtual void OnActionExecuting(ActionExecutingContext filterContext)
         9:     {
        10:         filterContext.HttpContext.Response.Write(string.Format("{0}.OnActionExecuting()<br/>", this.GetType().Name));
        11:     }
        12: }
        13:  
        14: public class FooAttribute : FilterBaseAttribute
        15: {}
        16: public class BarAttribute : FilterBaseAttribute
        17: {
        18:     public override void OnActionExecuting(ActionExecutingContext filterContext)
        19:     {
        20:         base.OnActionExecuting(filterContext);
        21:         filterContext.Result = new EmptyResult();
        22:     }
        23: }
        24: public class BazAttribute : FilterBaseAttribute
        25: {}

      然后我們定義了如下一個HomeController,上面定義的三個ActionFilter特性被應用到了Action方法Index上。我們對三個ActionFilter特性的Order屬性作了相應地設置使它們可以按照我們希望的順序(FooAttribute =>BarAttribute =>BazAttribute)執行。

         1: public class HomeController : Controller
         2: {
         3:     [Foo(Order = 1)]
         4:     [Bar(Order = 2)]
         5:     [Baz(Order = 3)]
         6:     public void Index()
         7:     {
         8:         Response.Write("Index...</br>");
         9:     }
        10: }

      image運行該程序后會在瀏覽器中呈現出如左圖所示的輸出結果,從中可以看出對于應用到Action方法Index上的三個ActionFilter,當BarAttribute的OnActionExecuting方法執行并對ActionExecutingContext的Result屬性進行了相應設置后,在它之前的ActionFilter的OnActionExecuted方法依然還是會執行。image

      這個簡單的實例演示揭示了應用到同一個Action方法上的ActionFilter鏈的執行機制:如果某個某個ActionFilter在執行OnActionExecuting方法過程中對ActionExecutingContext的Result屬性進行了設置,后續的ActionFilter和目標Action方法將不會再執行。此時ActionExecutedContext對象被創建,通過ActionExecutingContext的Result屬性表示的ActionResulut對象將會賦值給ActionExecutedContext的Result屬性。然后以前一個ActionFilter作為起點將創建的ActionExecutedContext對象作為輸入參數調用它們的OnActionExecuted方法。右圖基本上揭示了整個ActionFilter鏈執行的流程。順便指出一點:某個ActionFilter在OnActionExecuted方法中對ActionExecutedContext的Result的設置對整個ActionFilter鏈的執行沒有影響。

      四、ActionFilter中的異常處理

      image通過上面的介紹我們知道了某個ActionFilter在執行OnActionExecuting/OnActionExecuted方法過程中設置ActionExecutingContext/ActionExecutedContext的Result屬性進行設置后會對整個ActionFilter鏈的執行造成怎樣的影響,接下來我們來討論一下如果某個ActionFilter在執行OnActionExecuting/OnActionExecuted方法拋出異常,整個ActionFilter鏈又會如何執行。

      如果第一個ActionFilter在執行OnActionExecuting或者OnActionExecuted方法的過程中出現異常,那么這個異常會被直接拋出。對于出現異常的并不是第一個ActionFilter,那么異常會被捕捉并據此創建一個ActionExecutedContext對象(其Canceled屬性為False)作為參數調用前一個ActionFilter的OnActionExecuted方法。在前一個ActionFilter的OnActionExecuted方法執行之后ActionExecutedContext的ExceptionHandled屬性為True,會按照正常的方式調用之前ActionFilter的OnActionExecuted方法。

      反之,如果ExceptionHandled屬性為False,則會直接將異常拋出來,而這個被拋出的異常又會被之前的ActionFilter捕捉到,而這個ActionFilter又會根據捕捉的異常創建一個ActionExecutedContext對象并調用自身的OnActionExecuted方法。如果異常是在非鏈頭的ActionFilter的OnActionExecuted方法中拋出的,處理流程與此類似。

      我們不妨舉例說明Action鏈在執行過程中對異常的處理。假設具有如左圖所示的4個ActionFilter被應用到目標Action方法上,現在Filter1、Filter2和Filter3的OnActionExecuting方法異常被正常調用,但是Filter4在執行OnActionExecuting方法的時候拋出一個異常。該異常會被Filter3捕捉,它會根據這個異常創建一個ActionExecutedContext對象,并作為參數調用自己的OnActionExecuted方法(步驟1)。

      如果Filter3在執行OnActionExecuted方法后ActionExecutedContext的ExceptionHandled屬性為False,它會直接將異常拋出來。再次拋出的異常又會被Filter2所捕捉,它按照Filter3的方式根據異常創建ActionExecutedContext對象并作為參數調用自己的OnActionExecuted方法(步驟2)。如果Filter2在執行OnActionExecuted方法的時候將ActionExecutedContext對象的ExceptionHandled屬性設置為True,那么在這之后會正常地調用Filter1的OnActionExecuted方法,最終不會有異常拋出(步驟3)。

      posted @ 2012-08-06 09:14  Artech  閱讀(18024)  評論(20)    收藏  舉報
      主站蜘蛛池模板: 久久蜜臀av一区三区| 亚洲欧美综合精品成| 精品人妻av区乱码| 无码国内精品人妻少妇| 国产情侣激情在线对白| 国产在线精品一区二区中文| 午夜丰满少妇性开放视频| 国产精品中文字幕综合| 日本高清视频在线www色| 在线精品另类自拍视频| 亚洲精品日韩在线丰满| 化州市| 亚洲天堂精品一区二区| 亚洲成人av在线系列| 黄冈市| 亚洲欧美另类久久久精品播放的| 日韩在线成年视频人网站观看| 和艳妇在厨房好爽在线观看| 精品国产一区二区三区蜜臀| 日韩国产精品中文字幕| 亚洲综合另类小说色区一| 国内精品人妻一区二区三区| 91福利一区福利二区| 罗平县| 一级国产在线观看高清| 国产成人精品手机在线观看| 免费观看全黄做爰大片| 好看的国产精品自拍视频| 国产亚洲精品在av| 亚洲全乱码精品一区二区| 亚洲精品一区二区在线播| 一区二区三区AV波多野结衣| 绝顶丰满少妇av无码| 少妇尿尿一区二区在线免费| 国产成人免费| 部精品久久久久久久久| 国产91精品一区二区麻豆| 日韩有码中文字幕国产| 亚洲跨种族黑人xxxxx| 精品超清无码视频在线观看| 精品久久久久久中文字幕|