跳至正文
首页 » 博客 » How to Create a Custom Action Filter in ASP.NET MVC

How to Create a Custom Action Filter in ASP.NET MVC

在ASP.NET MVC中,过滤器用于在请求处理的不同级别注入逻辑,并允许我们在控制器之间共享逻辑。例如,假设我们要在控制器上运行安全逻辑或日志记录逻辑。为此,我们将编写一个包含这些逻辑的过滤器,并在所有控制器上启用它们。当我们在所有控制器或操作中启用过滤器时,过滤器会启用即将到来的HTTP请求。

让我们考虑一个日志记录的场景: 对于每个传入的请求,我们需要根据一些逻辑将一些数据记录到文件中。如果我们不在自定义过滤器中创建此逻辑,那么我们将不得不为每个控制器的操作编写逻辑。这种机制将导致两个问题:

  1. 重复代码; 和
  2. 违反单一责任原则; 行动现在将执行额外的日志记录任务。

我们可以通过将日志记录逻辑放在自定义操作过滤器中并在所有控制器级别应用过滤器来缓解上述问题。

您是否遇到过如下图所示的源代码?[Authorize] 是一个授权过滤器,它在任何HTPP请求或操作方法执行之前执行。授权过滤器是MVC的一部分,但如果需要,我们也可以创建一个自定义过滤器。

在ASP.NET MVC中,有四种类型的过滤器:

  1. 身份验证筛选器
  2. 授权筛选器
  3. 操作筛选器
  4. 结果筛选器
  5. 异常筛选器

运行各种过滤器的顺序如下:

  • 该身份验证筛选器先于任何其他筛选器或操作方法
  • 运行

  • 该授权筛选器在身份验证筛选器之后运行,并在任何其他筛选器或操作方法
  • 之前运行

  • 操作筛选器运行之前和之后的任何操作方法
  • 结果过滤器运行之前和之后执行任何操作结果
  • 异常筛选器运行仅当操作方法、筛选器或操作结果引发异常

在图中,我们可以描述过滤器执行的顺序,如下所示:

每个过滤器都有自己的用途,但是,大多数时候您会发现自己正在编写一个自定义操作过滤器。它们在执行动作之前和之后被执行。

自定义操作筛选器

我们出于各种原因编写自定义操作过滤器。我们可能有一个自定义操作过滤器用于日志记录,或者在执行任何操作之前将数据保存到数据库。我们也可以有一个用于从数据库中获取数据并将其设置为应用程序的全局值。我们可以出于各种原因创建自定义操作过滤器,包括但不限于:

  • 创建特权授权
  • 记录用户请求
  • 预处理图像上传
  • 提取数据以显示在布局菜单中
  • 本地化的应用程序
  • 读取浏览器用户代理信息以执行特定任务
  • 缓存等。

要创建自定义操作过滤器,我们需要执行以下任务:

  1. 创建一个类
  2. 继承它从ActionFilterAttribute
  3. 重写至少下列方法之一:
  • OnActionExecuting-在执行控制器操作之前调用此方法。
  • Onaction已执行-此方法在执行控制器操作后调用。
  • OnResultExecuting-在执行控制器操作结果之前调用此方法。
  • Onresult已执行-在执行控制器操作结果后调用此方法。

让我们创建一个自定义操作过滤器,它将以最简单的方式执行两个任务。当然,您可以在自定义操作过滤器中编写更复杂的代码,但是我们将创建一个名为MyFirstCustomFilter的自定义过滤器, 它将执行以下两个任务:

  1. 设置一些数据值在全局ViewBag。
  2. 将传入的请求记录到控制器操作方法。

可以创建过滤器,如下面的清单所示:

使用系统System.Diagnostics使用System.Web.Mvc使用命名空间: WebApplication1{    MyFirstCustomFilter: ActionFilterAttribute公共{        OnResultExecuting (public重写void filterContext){            // 你可以获取数据从数据库这里filterContext.Controller.ViewBag.GreetMesssage = "Hello Foo";            基地。OnResultExecuting(filterContext);}        OnActionExecuting (public重写void (ActionExecutingContext filterContext){            var controllerName = filterContext.RouteData.Values [] "控制器"var actionName = filterContext.RouteData.Values[ "action" ];            var message = String.Format( “{0} 控制器:{1} action:{2}”“onactionexecuting” ,controllerName,actionName);Debug.WriteLine (“操作过滤器日志” 消息);            基地。OnActionExecuting(filterContext);}}}

在上面的清单中,我们只是为正在执行的控制器设置ViewBag属性。ViewBag属性将在执行控制器操作结果之前设置,因为我们正在重写OnResultExecuting方法。此外,我们正在重写OnActionExecuting来记录有关控制器的操作方法的信息。

现在我们已经创建了自定义操作过滤器。现在我们可以在三个可能的级别上应用它:

  • 作为全局筛选器
  • 在控制器级别
  • 在操作级别

应用为全局筛选器

我们可以通过将过滤器添加到App_Start \ FilterConfig中的全局过滤器来在全局级别应用自定义过滤器。一旦在全局级别添加,过滤器将可用于MVC应用程序中的所有控制器。

公共FilterConfig{        RegisterGlobalFilters (GlobalFilterCollection筛选器) 公共静态void{filters.Add( 新增HandleErrorAttribute ());filters.Add( 新建MyFirstCustomFilter ());}}

筛选器在控制器级别

要在控制器级别应用过滤器,我们可以将其作为属性应用于特定控制器。当作为控制器级别应用时,该动作将可用于特定控制器的所有动作。我们可以将MyFirstCustomFilter应用于HomeController,如下面的清单所示:

[MyFirstCustomFilter]    HomeController: Controller公共{        公共ActionResult索引 (){            返回视图 ();}}

筛选器在操作级别

最后,要在特定操作中应用过滤器,我们可以将其应用为操作的属性,如下面的清单所示:

[MyFirstCustomFilter]        公共ActionResult联系人 (){ViewBag.Message =: “您的联系人页面。”            返回视图 ();}

这就是自定义操作过滤器!我希望你觉得这篇文章有用,并感谢您的阅读。有什么要补充的吗?请随时发表评论!</p