随着技术的发展,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:
- OnResourceExecuting 在筛选器管道的其余阶段之前运行代码。例如,
OnResourceExecuting 在模型绑定之前运行代码。 - OnResourceExecuted 在管道的其余阶段完成之后运行代码。
- 异常筛选器Exception Filter在向响应正文写入任何内容之前,对未经处理的异常应用全局策略。
- 对于必须围绕视图或格式化程序的执行的逻辑,会很有用。
下图展示了Filter筛选器类型在筛选器管道中的交互方式:Filter实现 所有的Filter都实现接口IFilterMetadata,根据不同的业务类型,派生出了五个接口,分别对应五大类Filter,如下所示:注意:上述五个接口还有对应异步接口(Async)。Filter作用域 Filter可以作用在Controller,Action,全局。下面的示例阐释了为同步操作筛选器运行筛选器方法的顺序:授权Filter
是筛选器管道中运行的第一个筛选器。 控制对操作方法的访问。 具有在它之前的执行的方法,但没有之后执行的方法。 如常用的RequireHttps就是授权筛选器,它实现了IAuthorizationFilter接口,并继承了Attirbute,所以可以作用于Controller或Action中。以限制请求的方式。using Microsoft.AspNetCore.Mvc.Filters; using System;
namespace Microsoft.AspNetCore.Mvc { // // 摘要: // An authorization filter that confirms requests are received over HTTPS. [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] public class RequireHttpsAttribute : Attribute, IAuthorizationFilter, IFilterMetadata, IOrderedFilter { public RequireHttpsAttribute();
public bool Permanent { get; set; }
public int Order { get; set; }
public virtual void OnAuthorization(AuthorizationFilterContext filterContext);
protected virtual void HandleNonHttpsRequest(AuthorizationFilterContext filterContext); } }
资源Filter 资源Filter在授权Filter之后执行,需要实现IResourceFilter接口。如下所示:using Microsoft.AspNetCore.Mvc.Filters;
namespace DemoCoreMVC.Filter { /// <summary> /// 同步版本 /// </summary> public class LogResourceFilter :Attribute, IResourceFilter { public void OnResourceExecuted(ResourceExecutedContext context) { //Action执行完成后执行 Console.WriteLine("********************On Resource Filter Executed********************"); }
public void OnResourceExecuting(ResourceExecutingContext context) { //授权Filter执行后执行。 Console.WriteLine("********************On Resource Filter Executing********************"); } }
/// <summary> /// 异步版本 /// </summary> public class AsynLogResouceFilter : Attribute, IAsyncResourceFilter { public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next) { Console.WriteLine("********************On Aysnc Resource Filter Executing********************"); var exceutedContext = await next(); Console.WriteLine("********************On Async Resource Filter Executed********************"); } } } 如果要使大部分管道短路,资源筛选器会很有用。例如,如果缓存命中,则缓存筛选器可以绕开管道的其余阶段。操作Filter 操作筛选器不应用于 Razor Pages。Razor Pages 支持 IPageFilter 和 IAsyncPageFilter。using Microsoft.AspNetCore.Mvc.Filters;
namespace DemoCoreMVC.Filter { public class DoDoActionFilter : Attribute, IActionFilter { public void OnActionExecuted(ActionExecutedContext context) { Console.WriteLine("********************On Action Executed********************"); }
public void OnActionExecuting(ActionExecutingContext context) { Console.WriteLine("********************On Action Executing********************"); } }
public class AsyncDoDoActionFilter : IAsyncActionFilter { public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { Console.WriteLine("********************On Async Action Executing********************"); await next(); Console.WriteLine("********************On Async Action Executed********************"); } } }
ActionExecutingContext 提供以下属性:ActionExecutedContext 提供 Controller 和 Result 以及以下属性:对于 IAsyncActionFilter ,一个向 ActionExecutionDelegate 的调用可以达到以下目的:异常Filter 下面的异常筛选器示例显示在开发应用时发生的异常的相关详细信息:using Microsoft.AspNetCore.Mvc.Filters;
namespace DemoCoreMVC.Filter { public class DoExceptionFilter :Attribute, IExceptionFilter { public void OnException(ExceptionContext context) { Console.WriteLine("********************On Exception********************"); } }
public class DoAsyncExceptionFilter : Attribute, IAsyncExceptionFilter { public async Task OnExceptionAsync(ExceptionContext context) { await Task.Run(() => { Console.WriteLine("********************On Exception Async********************"); });
} } }
没有之前和之后的事件。 实现 OnException 或 OnExceptionAsync。 处理 Razor 页面或控制器创建、模型绑定、操作筛选器或操作方法中发生的未经处理的异常。 请不要捕获资源筛选器、结果筛选器或 MVC 结果执行中发生的异常。 若要处理异常,请将 ExceptionHandled 属性设置为 true 或分配 Result 属性。这将停止传播异常。异常筛选器无法将异常转变为“成功”。只有操作筛选器才能执行该转变。非常适合捕获发生在操作中的异常。 并不像错误处理中间件那么灵活。 建议使用中间件处理异常。基于所调用的操作方法,仅当错误处理不同时,才使用异常筛选器。例如,应用可能具有用于 API 终结点和视图/HTML 的操作方法。API 终结点可以将错误信息返回为 JSON,而基于视图的操作可能会以 HTML 形式返回错误页。结果Filter
结果Filter,示例如下: using Microsoft.AspNetCore.Mvc.Filters;
namespace DemoCoreMVC.Filter { public class DoResultFilter :Attribute, IResultFilter { public void OnResultExecuted(ResultExecutedContext context) { Console.WriteLine("********************On Result Executed********************"); }
public void OnResultExecuting(ResultExecutingContext context) { Console.WriteLine("********************On Result Executing********************"); } }
public class DoAysncResultFilter :Attribute, IAsyncResultFilter { public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) { Console.WriteLine("********************On Result Execution Async Executing********************"); await next(); Console.WriteLine("********************On Result Execution Async Executed********************"); } }
}
Filter测试 将写好的过滤器,放在Home/Index上,如下所示:[DoExceptionFilter] [LogResourceFilter] [DoResultFilter] [DoDoActionFilter] public IActionResult Index() { _logger.LogInformation("Hello, 这是首页!"); return View(); } 说明:异常过滤器没有输出内容,是因为没有异常产生。授权过滤器没有添加,在所有过滤器之前开始,所有过滤器之后结束。Filter全局应用 Filter可以应用在单个Controller或Action上,也可以进行全局应用,代码如下所示:builder.Services.AddControllersWithViews(option => { option.Filters.Add<LogResourceFilter>(); option.Filters.Add<DoExceptionFilter>(); option.Filters.Add<DoResultFilter>(); option.Filters.Add<DoDoActionFilter>(); });
参考文档 官方文档:https://learn.microsoft.com/zh-cn/aspnet/core/mvc/controllers/filters?view=aspnetcore-6.0以上就是ASP.NET Core MVC 从入门到精通之Filter的全部内容。 关于ASP.NET Core MVC 从入门到精通其他文章,可通过以下链接查看:
|