首页 > 编程语言 >ASP.NET Core MVC 从入门到精通之Filter

ASP.NET Core MVC 从入门到精通之Filter

时间:2023-06-21 19:22:07浏览次数:43  
标签:Core ASP Filter Mvc Result Filters 筛选 public

随着技术的发展,ASP.NET Core MVC也推出了好长时间,经过不断的版本更新迭代,已经越来越完善,本系列文章主要讲解ASP.NET Core MVC开发B/S系统过程中所涉及到的相关内容,适用于初学者,在校毕业生,或其他想从事ASP.NET Core MVC 系统开发的人员。

经过前几篇文章的讲解,初步了解ASP.NET Core MVC项目创建,启动运行,以及命名约定,创建控制器,视图,模型,接收参数,传递数据ViewData,ViewBag,路由,页面布局,wwwroot和客户端库,Razor语法,EnityFrameworkCore与数据库,HttpContext,Request,Response,Session,序列化,文件上传,自动映射,Html辅助标签,模型校验,鉴权、授权基础,Identity入门,日志管理等内容,今天继续讲解ASP.NET Core MVC 中Filter(筛选器)等相关内容,仅供学习分享使用。

什么是Filter?

Filter又称为筛选器,过滤器。在ASP.NET Core MVC项目中,通过使用Filter,可以在请求处理管道的特定位置之前或之后运行代码。可以创建自定义Filter,用于处理横切关注点,类似于AOP面向切面编程。对于创建Filter,可以减少代码的复制,例如,错误处理异常筛选器可以合并错误处理。

Filter工作原理

从请求开始,到请求结束,经过一系列的节点,组成了调用管道。Filter在ASP.NET Core MVC的调用管道内运行,过滤器相当于在管道中设置的几个钩子,用于执行特定的代码。

Filter类型

根据不同的处理功能,筛选器主要分为以下几类:

  • 授权筛选器AuthorizationFilter:

    • 首先运行。
    • 确定用户是否获得请求授权。
    • 如果请求未获授权,可以让管道短路。
  • 资源筛选器Resource Filter:

    • 授权后运行。
    • OnResourceExecuting 在筛选器管道的其余阶段之前运行代码。 例如,OnResourceExecuting 在模型绑定之前运行代码。
    • OnResourceExecuted 在管道的其余阶段完成之后运行代码。
  • 操作筛选器Action Filter:

    • 在调用操作方法之前和之后立即运行。
    • 可以更改传递到操作中的参数。
    • 可以更改从操作返回的结果。
    • 不可在 Razor Pages 中使用。
  • 异常筛选器Exception Filter:在向响应正文写入任何内容之前,对未经处理的异常应用全局策略。

  • 结果筛选器Result Filter:

    • 在执行操作结果之前和之后立即运行。
    • 仅当操作方法成功执行时才会运行。
    • 对于必须围绕视图或格式化程序的执行的逻辑,会很有用。

 下图展示了Filter筛选器类型在筛选器管道中的交互方式:

Filter实现

所有的Filter都实现接口IFilterMetadata,根据不同的业务类型,派生出了五个接口,分别对应五大类Filter,如下所示:

注意:上述五个接口还有对应异步接口(Async)。

 Filter作用域

Filter可以作用在Controller,Action,全局。下面的示例阐释了为同步操作筛选器运行筛选器方法的顺序:

 

 

授权Filter

授权筛选器:

  • 是筛选器管道中运行的第一个筛选器。
  • 控制对操作方法的访问。
  • 具有在它之前的执行的方法,但没有之后执行的方法。

如常用的RequireHttps就是授权筛选器,它实现了IAuthorizationFilter接口,并继承了Attirbute,所以可以作用于Controller或Action中。以限制请求的方式。

 1 using Microsoft.AspNetCore.Mvc.Filters;
 2 using System;
 3 
 4 namespace Microsoft.AspNetCore.Mvc
 5 {
 6     //
 7     // 摘要:
 8     //     An authorization filter that confirms requests are received over HTTPS.
 9     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
10     public class RequireHttpsAttribute : Attribute, IAuthorizationFilter, IFilterMetadata, IOrderedFilter
11     {
12         public RequireHttpsAttribute();
13 
14         //
15         // 摘要:
16         //     Specifies whether a permanent redirect, 301 Moved Permanently, should be used
17         //     instead of a temporary redirect, 302 Found.
18         public bool Permanent { get; set; }
19         //
20         // 值:
21         //     Default is int.MinValue + 50 to run this Microsoft.AspNetCore.Mvc.Filters.IAuthorizationFilter
22         //     early.
23         public int Order { get; set; }
24 
25         //
26         // 摘要:
27         //     Called early in the filter pipeline to confirm request is authorized. Confirms
28         //     requests are received over HTTPS. Takes no action for HTTPS requests. Otherwise
29         //     if it was a GET request, sets Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext.Result
30         //     to a result which will redirect the client to the HTTPS version of the request
31         //     URI. Otherwise, sets Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext.Result
32         //     to a result which will set the status code to 403 (Forbidden).
33         public virtual void OnAuthorization(AuthorizationFilterContext filterContext);
34         //
35         // 摘要:
36         //     Called from Microsoft.AspNetCore.Mvc.RequireHttpsAttribute.OnAuthorization(Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext)
37         //     if the request is not received over HTTPS. Expectation is Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext.Result
38         //     will not be null after this method returns.
39         //
40         // 参数:
41         //   filterContext:
42         //     The Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext to update.
43         //
44         // 言论:
45         //     If it was a GET request, default implementation sets Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext.Result
46         //     to a result which will redirect the client to the HTTPS version of the request
47         //     URI. Otherwise, default implementation sets Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext.Result
48         //     to a result which will set the status code to 403 (Forbidden).
49         protected virtual void HandleNonHttpsRequest(AuthorizationFilterContext filterContext);
50     }
51 }

 

资源Filter

资源Filter在授权Filter之后执行,需要实现IResourceFilter接口。如下所示:

 1 using Microsoft.AspNetCore.Mvc.Filters;
 2 
 3 namespace DemoCoreMVC.Filter
 4 {
 5     /// <summary>
 6     /// 同步版本
 7     /// </summary>
 8     public class LogResourceFilter :Attribute, IResourceFilter
 9     {
10         public void OnResourceExecuted(ResourceExecutedContext context)
11         {
12             //Action执行完成后执行
13             Console.WriteLine("********************On Resource Filter Executed********************");
14         }
15 
16         public void OnResourceExecuting(ResourceExecutingContext context)
17         {
18             //授权Filter执行后执行。
19             Console.WriteLine("********************On Resource Filter Executing********************");
20         }
21     }
22 
23     /// <summary>
24     /// 异步版本
25     /// </summary>
26     public class AsynLogResouceFilter : Attribute, IAsyncResourceFilter
27     {
28         public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
29         {
30             Console.WriteLine("********************On Aysnc Resource Filter Executing********************");
31             var exceutedContext =  await next();
32             Console.WriteLine("********************On Async Resource Filter Executed********************");
33         }
34     }
35 }

如果要使大部分管道短路,资源筛选器会很有用。 例如,如果缓存命中,则缓存筛选器可以绕开管道的其余阶段。

操作Filter

操作筛选器不应用于 Razor Pages。 Razor Pages 支持 IPageFilter 和 IAsyncPageFilter。

操作筛选器:

  • 实现 IActionFilter 或 IAsyncActionFilter 接口。
  • 它们的执行围绕着操作方法的执行。

以下代码显示示例操作筛选器:

 1 using Microsoft.AspNetCore.Mvc.Filters;
 2 
 3 namespace DemoCoreMVC.Filter
 4 {
 5     public class DoDoActionFilter : Attribute, IActionFilter
 6     {
 7         public void OnActionExecuted(ActionExecutedContext context)
 8         {
 9             
10             Console.WriteLine("********************On Action Executed********************");
11         }
12 
13         public void OnActionExecuting(ActionExecutingContext context)
14         {
15             Console.WriteLine("********************On Action Executing********************");
16         }
17     }
18 
19     public class AsyncDoDoActionFilter : IAsyncActionFilter
20     {
21         public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
22         {
23             
24             Console.WriteLine("********************On Async Action Executing********************");
25             await next();
26             Console.WriteLine("********************On Async Action Executed********************");
27         }
28     }
29 }

 

ActionExecutingContext 提供以下属性:

  • ActionArguments - 用于读取操作方法的输入。
  • Controller - 用于处理控制器实例。
  • Result - 设置 Result 会使操作方法和后续操作筛选器的执行短路。

ActionExecutedContext 提供 Controller 和 Result 以及以下属性:

  • Canceled - 如果操作执行已被另一个筛选器设置短路,则为 true。
  • Exception - 如果操作或之前运行的操作筛选器引发了异常,则为非 NULL 值。 将此属性设置为 null:
    • 有效地处理异常。
    • 执行 Result,从操作方法中将它返回。

对于 IAsyncActionFilter,一个向 ActionExecutionDelegate 的调用可以达到以下目的:

  • 执行所有后续操作筛选器和操作方法。
  • 返回 ActionExecutedContext

异常Filter

异常筛选器:

  • 实现 IExceptionFilter 或 IAsyncExceptionFilter。
  • 可用于实现常见的错误处理策略。

下面的异常筛选器示例显示在开发应用时发生的异常的相关详细信息:

 1 using Microsoft.AspNetCore.Mvc.Filters;
 2 
 3 namespace DemoCoreMVC.Filter
 4 {
 5     public class DoExceptionFilter :Attribute, IExceptionFilter
 6     {
 7         public void OnException(ExceptionContext context)
 8         {
 9             Console.WriteLine("********************On Exception********************");
10         }
11     }
12 
13     public class DoAsyncExceptionFilter : Attribute, IAsyncExceptionFilter
14     {
15         public async Task OnExceptionAsync(ExceptionContext context)
16         {
17             await Task.Run(() =>
18             {
19                 Console.WriteLine("********************On Exception Async********************");
20             });
21             
22         }
23     }
24 }

异常筛选器:

  • 没有之前和之后的事件。
  • 实现 OnException 或 OnExceptionAsync。
  • 处理 Razor 页面或控制器创建、模型绑定、操作筛选器或操作方法中发生的未经处理的异常。
  • 请不要捕获资源筛选器、结果筛选器或 MVC 结果执行中发生的异常。

若要处理异常,请将 ExceptionHandled 属性设置为 true 或分配 Result 属性。 这将停止传播异常。 异常筛选器无法将异常转变为“成功”。 只有操作筛选器才能执行该转变。

异常筛选器:

  • 非常适合捕获发生在操作中的异常。
  • 并不像错误处理中间件那么灵活。

建议使用中间件处理异常。 基于所调用的操作方法,仅当错误处理不同时,才使用异常筛选器。 例如,应用可能具有用于 API 终结点和视图/HTML 的操作方法。 API 终结点可以将错误信息返回为 JSON,而基于视图的操作可能会以 HTML 形式返回错误页。

结果Filter

结果筛选器:

  • 实现接口:
    • IResultFilter 或 IAsyncResultFilter
    • IAlwaysRunResultFilter 或 IAsyncAlwaysRunResultFilter
  • 它们的执行围绕着操作结果的执行。
 1 using Microsoft.AspNetCore.Mvc.Filters;
 2 
 3 namespace DemoCoreMVC.Filter
 4 {
 5     public class DoResultFilter :Attribute, IResultFilter
 6     {
 7         public void OnResultExecuted(ResultExecutedContext context)
 8         {
 9             Console.WriteLine("********************On Result Executed********************");
10         }
11 
12         public void OnResultExecuting(ResultExecutingContext context)
13         {
14             Console.WriteLine("********************On Result Executing********************");
15         }
16     }
17 
18     public class DoAysncResultFilter :Attribute, IAsyncResultFilter
19     {
20         public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
21         {
22             Console.WriteLine("********************On Result Execution Async Executing********************");
23             await next();
24             Console.WriteLine("********************On Result Execution Async Executed********************");
25         }
26     }
27 
28 }

Filter测试

将写好的过滤器,放在Home/Index上,如下所示:

1 [DoExceptionFilter]
2 [LogResourceFilter]
3 [DoResultFilter]
4 [DoDoActionFilter]
5 public IActionResult Index()
6 {
7     _logger.LogInformation("Hello, 这是首页!");
8     return View();
9 }

测试如下所示:

说明:异常过滤器没有输出内容,是因为没有异常产生。授权过滤器没有添加,在所有过滤器之前开始,所有过滤器之后结束。

Filter全局应用

Filter可以应用在单个Controller或Action上,也可以进行全局应用,代码如下所示:

1 builder.Services.AddControllersWithViews(option =>
2 {
3     option.Filters.Add<LogResourceFilter>();
4     option.Filters.Add<DoExceptionFilter>();
5     option.Filters.Add<DoResultFilter>();
6     option.Filters.Add<DoDoActionFilter>();
7 });

全局测试如下所示:

以上就是ASP.NET Core MVC 从入门到精通之Filter的全部内容。

参考文档

官方文档:https://learn.microsoft.com/zh-cn/aspnet/core/mvc/controllers/filters?view=aspnetcore-6.0

标签:Core,ASP,Filter,Mvc,Result,Filters,筛选,public
From: https://www.cnblogs.com/hsiang/p/17495239.html

相关文章

  • 聊聊 ASP.NET 6 整洁架构开发模板
    大家好,我是Edison。最近看了一些整洁架构(CleanArchitecture)的文章,自己和同事也简单写了一个基于整洁架构的ASP.NET6开发模板在玩。这里就仅仅抛个砖,案例主要以自己根据小组实际情况做了一些裁剪,可能不具有通用的应用性,大家看看就好。整洁架构的产生背景微服务架构让DDD(领域驱......
  • 转:ASP.NET Core Identity系列之八
    转自:https://mp.weixin.qq.com/s?__biz=MzA3NDM1MzIyMQ==&mid=2247486215&idx=1&sn=9bd90b0c1d2d5583b8da324cbb56c5a6这一节我们主要介绍在ASP.NETCoreIdentity中使用策略进行授权,Policy是用户必须具备一组集合为授权访问应用程序上的资源。IdentityPolicy的授权可以包含对用......
  • 转:ASP.NET Core Identity 系列之五
    转自:https://mp.weixin.qq.com/s?__biz=MzA3NDM1MzIyMQ==&mid=2247486194&idx=1&sn=a213c72dd0564c31a7624c6d99f0d277这节我们将介绍在Identity中如何使用Role,在我们应用程序中可以通过ASP.NETCoreIdentity创建Roles并且该角色可以包含一系列权限来执行应用程序的一系列活动......
  • 转:ASP.NET Core Identity 系列之四
    转自:https://mp.weixin.qq.com/s?__biz=MzA3NDM1MzIyMQ==&mid=2247486183&idx=1&sn=baeb28f24399a9b0203f33185e1399a6这节我们主要介绍ASP.NETCoreIdentity认证,认证是决定用户是否能够成功登录应用程序的一个过程,用户通过提供自己的用户名和密码来证明他们自己是真实用户,当登......
  • 专业数据科学家的IDE-DataSpell 2023 mac/win版
    DataSpell2023是一款专为数据科学家设计的集成开发环境(IDE),旨在提供强大的数据分析和机器学习工具,帮助用户更高效地处理和分析大规模数据集。→→↓↓载DataSpell2023mac/win版 DataSpell2023提供了丰富的功能和工具,使数据科学家能够完整地执行整个数据科学项目的流程,从......
  • TSN CoreSolutuon开启时间敏感网络测试自动化新篇章
    随着下一代车载网络的快速发展,OEM和TIER1在开发和验证复杂车载网络通信的过程中面临很多新的挑战。为了更好地满足网络测试方面的需求,TSNSystems在原先TSNBox和TSNTools测量工具的基础上,集成了相关的应用程序接口,用来支持各种场景下的自动化测试。这一测试工具链也被正式更名为......
  • net Core基础API 命名空间定义
    ●System.Collections:定义了常用的集合类型。●System.Console:提供API完成基本的控制台操作。●System.Data:提供用于访问数据库的API,相当于原来的ADO.NET。●System.Diagnostics:提供基本的诊断、调试和追踪的API。●System.DirectoryServices:提供基于AD(ActiveDirectory)管理......
  • 【.NET Core】配置复用、替换(GSoft.Extensions.Configuration.Substitution)【转】
    .NET是一个非常强大的框架,它允许开发人员管理来自各种源(如JSON文件、环境变量等)的应用程序设置。但是,有时开发人员需要一种方法来引用和替换其他设置中的配置值,以避免在多个地方维护相同的值,从而使配置文件变得混乱和难以维护。为了解决这个问题,我们可以使用GSoft.Extensions......
  • 如何快速发现 ASP.NET Core 应用程序中的服务生命周期问题?【转】
    在ASP.NETCore中,内置了非常强大的依赖注入容器功能。但是,如果不正确使用,也可能会引起一些问题。问题下面我们通过一段示例代码来说明这个问题。public interface IServiceA{    string Get();}public interface IServiceB{    string Get();}public class S......
  • SpringMVC中接收前端传递的参数,设置了编码过滤器filter,但在控制台中还是出现乱码问题
    SpringMVC中接收前端传递的参数,设置了编码过滤器filter,但在控制台中还是出现乱码问题。 在SpringMVC中遇到乱码问题不要慌,先配个SpringMVC的自带编码过滤器试试 <filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.spr......