ASP.Net MVC過濾器


在ASP.NET MVC中,控制器定義的操作方法通常與可能的使用者互動具有一對一的關係,但有時候您希望在呼叫操作方法之前或者在操作方法執行之後執行邏輯。

為了支援這個功能,ASP.NET MVC提供了過濾器。 過濾器是一個自定義類,它提供了一種宣告式和程式式的方法,可將操作前和操作後行為新增到控制器操作方法中。

動作過濾器

動作過濾器是一個屬性,可以將其應用於控制器動作或整個控制器,以修改執行動作的方式。 ASP.NET MVC框架包含幾個操作過濾器 -

  • OutputCache - 將控制器操作的輸出快取指定的時間量。
  • HandleError - 處理執行控制器操作時引發的錯誤。
  • Authorize - 使能夠限制對特定使用者或角色的存取。

過濾器的型別

ASP.NET MVC框架支援四種不同型別的過濾器 -

  • 授權過濾器 - 實現IAuthorizationFilter屬性。
  • 動作過濾器 - 實現IActionFilter屬性。
  • 結果過濾器 - 實現IResultFilter屬性。
  • 異常過濾器 - 實現IExceptionFilter屬性。

過濾器按上面列出的順序執行。例如,授權過濾器始終在每個其他型別的過濾器之後執行操作過濾器和異常過濾器之前執行。

授權過濾器 用於實現控制器操作的身份驗證和授權。 例如,授權過濾器是授權過濾器的一個例子。

下面來看一個簡單的例子,建立一個新的ASP.Net MVC專案。開啟Visual Studio,然後單擊選單:檔案 -> 新建 -> 專案 選項。建立一個名稱為:MVCFiltersDemo 的MVC專案。

詳細建立過程請參考:/14/125/3680.html

通過在解決方案資源管理器 中右鍵單擊 Controllers 檔案夾來新增一個控制元件器:HomeController。在彈出選單項中選擇:新增 -> 控制器

應用操作篩選器

動作過濾器可以應用於單獨的控制器動作或整個控制器。 例如,操作篩選器OutputCache應用於名為Index()的操作,該操作返回字串。 此過濾器會將該操作返回的值快取15秒。

為了使這個實現這個例子,讓我們修改控制器類通過改變稱為Index操作方法使用下面的程式碼 -

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MVCFiltersDemo.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        // GET: Home
        [OutputCache(Duration = 15)]
        public string Index()
        {
            return "This is ASP.Net MVC Filters Tutorial";
        }
    }
}

執行此應用程式時,將看到瀏覽器正在顯示Index操作方法的結果,如下所示 -

再新增另一個操作方法,它用於顯示當前時間 -

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MVCFiltersDemo.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        [OutputCache(Duration = 15)]
        public string Index()
        {
            return "This is ASP.Net MVC Filters Tutorial";
        }
        // 返回當前時間
        [OutputCache(Duration = 20)]
        public string GetCurrentTime()
        {
            return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        }
    }
}

請求以下URL:http://localhost:54713/Home/GetCurrentTime,將收到以下輸出 -

如果重新整理瀏覽器,則會看到相同的時間,因為該操作被快取了20秒。 20秒後重新整理它將被更新。

自定義過濾器

要建立自己的自定義過濾器,ASP.NET MVC框架提供了一個叫作ActionFilterAttribute的基礎類別。 這個類實現了IActionFilterIResultFilter介面,都是從Filter類派生的。

下面來看看看自定義過濾器的一個簡單的例子,通過在專案中建立一個新的檔案夾:ActionFilters 。新增一個類,右鍵單擊ActionFilters 檔案夾並選擇:新增 ->

在類名稱欄位中輸入MyLogActionFilter,然後單擊「新增」 按鈕。

這個類將從ActionFilterAttribute派生,它是一個基礎類別,並覆蓋下面的方法。 以下是MyLogActionFilter的完整實現。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace MVCFiltersDemo.ActionFilters
{
    public class MyLogActionFilter: ActionFilterAttribute
    {        

        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);
            System.Console.WriteLine("############################# YES ##################");
            Debug.WriteLine(message, "Action Filter Log");
        }
    }

}

現在,使用以下程式碼將紀錄檔過濾器應用於HomeController控制器。

using MVCFiltersDemo.ActionFilters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MVCFiltersDemo.Controllers
{
    [MyLogActionFilter]
    public class HomeController : Controller
    {
        // GET: Home
        [OutputCache(Duration = 10)]
        public string Index()
        {
            return "This is ASP.Net MVC Filters Tutorial";
        }

        // 返回當前時間
        [OutputCache(Duration = 10)]
        public string GetCurrentTime()
        {
            return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        }
    }
}

開啟專案中的App_Start,開啟檔案FilterConfig.cs ,新增以下程式碼註冊過濾器:MyLogActionFilter -

using MVCFiltersDemo.ActionFilters;
using System.Web;
using System.Web.Mvc;

namespace MVCFiltersDemo
{
    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
            // 註冊自定義Action過濾器:優先順序最低,但是可以作用到所有的控制器和Action  
            filters.Add(new MyLogActionFilter());
        }
    }
}

執行應用程式,然後觀察輸出視窗。應該會看到類似(輸出的最後幾行)的結果 -

如上圖所示,處理動作的每個階段都有被記錄到Visual Studio輸出視窗中了。