ASP.NET MVC筆記 之 Action 過濾器

來源:互聯網
上載者:User

    Action 過濾器在代碼中體現為添加到Action上方的屬性,MVC架構套件含了一些過濾器,如:
    OutputCache –指示Controller在指定時間內緩衝返回的結果。
    HandleError –處理Contrller中Action拋出的異常
    Authorize – 約束特定使用者或角色對Action的訪問
    另外你還可以自己定義過濾器,比如:你想使用自訂的驗證機制;你想修改Action返回的資料等等。
    使用Action 過濾器
     Action 過濾器不僅可以控制單個Action,也可以控制整個Contrller。同時,一個Action可以應用多個過濾器。比如:

public class DataController : Controller
{
   [OutputCache(Duration=10)]
   public string Index()
   {
       return DateTime.Now.ToString("T");
   }
}

這個Action返回了目前時間,但是你若在10秒鐘內重新整理介面,你會一直得到同一個值,因為這裡使用了OutputCache(Duration=10)
    過濾器的類型
    ASP.NET MVC 架構支援以下幾種過濾器:
    1、Authorization 過濾器– 實現了 IAuthorizationFilter 介面。這一類的過濾器用來實現使用者驗證和對Action的訪問授權。比如Authorize 就屬於Authorization 過濾器。
    2、Action 過濾器– 實現了 IActionFilter 介面。它可以包含一些Action執行前或者執行後的邏輯,比如有一些過濾器專門用來修改Action返回的資料。
    3、Result 過濾器– 實現了 IResultFilter 介面。它可以包含一些view result產生前或者產生後的邏輯,比如有一些過濾器專門用來修改視圖向瀏覽器展現前的結果。
    4、Exception 過濾器– 實現了IExceptionFilter 介面。它用以用來處理Action或者Result的錯誤,也可以記錄錯誤。
    過濾器的預設執行順序也和上面的列表相同,比如Authorization 過濾器會先於Action 過濾器執行,而Exception 過濾器總會在最後執行。當然你也可以根據需要通過Order屬性設定過濾器執行的順序。
    自訂過濾器
    自訂過濾器必須繼承System.Web.Mvc.FilterAttribute ,並且實現上述幾個介面中的一個或者多個。MVC架構為了方便開發人員,預定義了一個ActionFilterAttribute 類,它已實現了IActionFilter 和IResultFilter 介面。你可以重載ActionFilterAttribute 類中以下幾個方法:
OnActionExecuting – 在Action執行之前調用。
OnActionExecuted – 在Action執行之後調用。
OnResultExecuting – 在Result產生之前調用。
OnResultExecuted – 在Result產生之前調用。
下面樣本一個類:    

Code
public class LogActionFilter : ActionFilterAttribute
     {
          public override void OnActionExecuting(ActionExecutingContext filterContext)
          {
               Log("OnActionExecuting", filterContext.RouteData);       
          }

          public override void OnActionExecuted(ActionExecutedContext filterContext)
          {
               Log("OnActionExecuted", filterContext.RouteData);       
          }

          public override void OnResultExecuting(ResultExecutingContext filterContext)
          {
               Log("OnResultExecuting", filterContext.RouteData);       
          }

          public override void OnResultExecuted(ResultExecutedContext filterContext)
          {
               Log("OnResultExecuted", filterContext.RouteData);       
          }

          private void Log(string methodName, RouteData routeData)
          {
               var controllerName = routeData.Values["controller"];
               var actionName = routeData.Values["action"];
               var message = String.Format("{0} controller:{1} action:{2}", methodName, controllerName, actionName);
               Debug.WriteLine(message, "Action Filter Log");
          }

     }

將LogActionFilter冠在某一個Action或者Controller上,就會列印對應Action的執行情況。如:

 

     [LogActionFilter]
     public class HomeController : Controller
     {}

OutputCache過濾器
      你可以使用OutputCache過濾器來緩衝的你查詢結果,這樣可以提高使用者體驗,也可以減少查詢次數。它有以下屬性:
Duration:緩衝的時間,以秒為單位,理論上緩衝時間可以很長,但實際上當系統資源緊張時,緩衝空間還是會被系統收回。
VaryByParam:以哪個欄位為標識來快取資料,比如當“ID”欄位變化時,需要改變緩衝(仍可保留原來的緩衝),那麼應該設VaryByParam為"ID"。這裡你可以設定以下幾個值:
* = 任何參數變化時,都改變緩衝。
none = 不改變緩衝。
以分號“;”為間隔的欄位名列表 = 列表中的欄位發生變化,則改變緩衝。

Location:快取資料放在何處。緩衝位置很重要,如果存在伺服器上,那麼所有使用者看到的緩衝視圖都會一樣,如果存在用戶端,那麼使用者只會看到自己的緩衝。比如:如果是一些私人資訊,那就不能存在伺服器上。你可以設定以下值:
· Any :預設值,輸出緩衝可位於產生請求的瀏覽器用戶端、參與請求的Proxy 伺服器(或任何其他伺服器)或處理請求的伺服器上。

· Client:輸出緩衝位於產生請求的瀏覽器用戶端上。

· Downstream 輸出緩衝可儲存在任何 HTTP 1.1 可緩衝裝置中,原始伺服器除外。這包括Proxy 伺服器和發出請求的用戶端。

· Server:輸出緩衝位於處理請求的 Web 服務器上。

· None:對於請求的頁,禁用輸出緩衝。

· ServerAndClient:輸出緩衝只能儲存在原始伺服器或發出請求的用戶端中。Proxy 伺服器不能緩衝響應。

NoStore:該屬性定義一個布爾值,用於決定是否阻止敏感資訊的二級儲存。
除了直接在Action或者類的定義前加上屬性,也可以使用設定檔,這樣就可以動態配置你的緩衝模式了。
在<system.web>節中,添加如下配置:

<caching>
<outputCacheSettings>
    <outputCacheProfiles>
        <add name="Cache1Hour" duration="3600" varyByParam="none"/>
    </outputCacheProfiles>
</outputCacheSettings>
</caching>

那麼在Controller中可以這樣使用:

[OutputCache(CacheProfile="Cache1Hour")]
public string Index()
{
   return DateTime.Now.ToString("T");
}

[擴充]在已經緩衝的頁面上添加動態內容
為了提高使用者體驗,我們會使用緩衝技術,但是有時我們會需要在頁面上改變內容,如:提供一些動態資訊、廣告的變化等。
此時我們可以調用 HttpResponse.WriteSubstitution() 方法。
例如:

 

<% Response.WriteSubstitution(News.RenderNews); %>

其中News.RenderNews是一個靜態方法,它的定義如下,這個方法用來隨機顯示三條廣告詞。   

Code
public class News
    {
        public static string RenderNews(HttpContext context)
        {
            var news = new List<string> 
                { 
                    "Gas prices go up!", 
                    "Life discovered on Mars!", 
                    "Moon disappears!" 
                };
            
            var rnd = new Random();
            return news[rnd.Next(news.Count)];
        }

    }

你甚至可以為Response.WriteSubstitution()方法擴充一個Helper方法,如下所示:
    

Code
public static class AdHelper
    {
        public static void RenderBanner(this HtmlHelper helper)
        {
            var context = helper.ViewContext.HttpContext;
            context.Response.WriteSubstitution(RenderBannerInternal);
        }

     private static string RenderBannerInternal(HttpContext context)
        {
            var ads = new List<string> 
                { 
                    "/ads/banner1.gif", 
                    "/ads/banner2.gif", 
                    "/ads/banner3.gif" 
                };

            var rnd = new Random();
            var ad = ads[rnd.Next(ads.Count)];
            return String.Format("<img src='{0}' />", ad);
        }

    }

那麼你就可以在頁面上如此調用:

 <% Html.RenderBanner(); %>

這樣就會每重新整理一次頁,改變一次映像。但是資料內容卻還是緩衝的,並不會因為你重新整理了頁面而重新查詢資料庫。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.