ASP.NET MVC – 过滤器
ASP.NET MVC – 过滤器
在 ASP.NET MVC 中,控制器定义通常与可能的用户交互具有一对一关系的操作方法,但有时您希望在调用操作方法之前或操作方法运行之后执行逻辑。
为了支持这一点,ASP.NET MVC 提供了过滤器。过滤器是自定义类,它提供声明性和编程方式来向控制器操作方法添加操作前和操作后行为。
动作过滤器
操作过滤器是一种属性,您可以将其应用于控制器操作或整个控制器,用于修改操作的执行方式。ASP.NET MVC 框架包括几个动作过滤器 –
-
OutputCache – 在指定的时间内缓存控制器操作的输出。
-
HandleError – 处理执行控制器操作时引发的错误。
-
授权– 使您能够限制对特定用户或角色的访问。
过滤器类型
ASP.NET MVC 框架支持四种不同类型的过滤器 –
-
授权过滤器– 实现 IAuthorizationFilter 属性。
-
动作过滤器– 实现 IActionFilter 属性。
-
结果过滤器– 实现 IResultFilter 属性。
-
异常过滤器– 实现 IExceptionFilter 属性。
过滤器按上面列出的顺序执行。例如,授权过滤器总是在动作过滤器之前执行,异常过滤器总是在所有其他类型的过滤器之后执行。
授权过滤器用于实现控制器动作的身份验证和授权。例如,授权过滤器是授权过滤器的一个示例。
让我们通过创建一个新的 ASP.Net MVC 项目来看看一个简单的例子。
步骤 1 – 打开 Visual Studio 并单击文件 → 新建 → 项目菜单选项。
一个新的项目对话框打开。
步骤 2 – 从左侧窗格中,选择模板 → Visual C# → Web。
步骤 3 – 在中间窗格中,选择 ASP.NET Web 应用程序。
第 4 步– 在名称字段中输入项目名称 MVCFiltersDemo,然后单击确定继续,您将看到以下对话框,要求您设置 ASP.NET 项目的初始内容。
第 5 步– 为简单起见,选择“空”选项并选中“添加文件夹和核心引用”部分中的 MVC 复选框,然后单击“确定”。
它将创建一个具有最少预定义内容的基本 MVC 项目。
步骤 6 – 要添加控制器,请右键单击解决方案资源管理器中的控制器文件夹,然后选择添加 → 控制器。
它将显示“添加脚手架”对话框。
步骤 7 – 选择 MVC 5 Controller – Empty 选项,然后单击“添加”按钮。
将出现添加控制器对话框。
第 8 步– 将名称设置为 HomeController,然后单击“添加”按钮。
您将在 Controllers 文件夹中看到一个新的 C# 文件“HomeController.cs”,该文件也已打开以在 Visual Studio 中进行编辑。
应用操作过滤器
动作过滤器可以应用于单个控制器动作或整个控制器。例如,操作过滤器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 [OutputCache(Duration = 15)] public string Index(){ return "This is ASP.Net MVC Filters Tutorial"; } } }
当您运行此应用程序时,您将看到浏览器正在显示 Index 操作方法的结果。
让我们添加另一个动作方法,它将显示当前时间。
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("T"); } } }
请求以下 URL,http://localhost:62833/Home/GetCurrentTime,您将收到以下输出。
如果刷新浏览器,您将看到相同的时间,因为该操作已缓存 20 秒。当您在 20 秒后刷新它时,它将被更新。
自定义过滤器
为了创建您自己的自定义过滤器,ASP.NET MVC 框架提供了一个称为 ActionFilterAttribute 的基类。此类实现了 IActionFilter 和 IResultFilter 接口,并且两者均派生自 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 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"); } } }
现在让我们使用以下代码将日志过滤器应用于 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("T"); } } }
运行应用程序,然后观察输出窗口。
如上面的屏幕截图所示,处理操作的阶段会记录到 Visual Studio 输出窗口中。