参考:
https://www.cnblogs.com/caofangsheng/p/10574559.html 【灰太狼的梦想博客】
https://www.cnblogs.com/aoede-jacqueline/p/mvc-filters.html 【梦中的Aoede博客】
https://www.jb51.net/article/107613.htm
什么是过滤器
- 过滤器(Filters)就是向请求处理管道中注入额外的逻辑;
- MVC框架里面的过滤器完全不同于ASP.NET平台里面的Request.Filters和Response.Filter对象,它们主要是实现请求和响应流的传输。通常我们所说的过滤器是指MVC框架里面的过滤器。
- 过滤器可以注入一些代码逻辑到请求处理管道中,是基于C#的Attribute的实现。当负责调用Action的类ControllerActionInvoker在调用执行Action的时候会检查Action上面的Attribute并查看这些Attribute是否实现了指定的接口,以便进行额外的代码注入处理
- 在ASP.NET MVC的请求处理过程中有19个管道事件,这些事件分布在请求处理的各个节点中,比如BeginRequest(开始处理请求时触发)、AuthenticateRequest(对请求进行身份验证时触发)、AuthorizeRequest(对请求进程授权时触发)…等等,过滤器的主要作用就是将我们的逻辑代码注入到这些请求处理管道中。
- 通过过滤器可以将与业务逻辑无关但经常需要执行的代码分离开,使我们的代码逻辑性更加清晰,代码更加简洁。
关于C#的Attribute参见:
https://blog.csdn.net/xiaouncle/article/details/70216951
https://blog.csdn.net/xiaouncle/article/details/70229119
https://www.cnblogs.com/zhaoyl9/p/12027938.html
https://www.jb51.net/article/197849.htm
过滤器的类型与作用
MVC给我们提供了四种过滤器【Authentication过滤器是在ASP.NET MVC 5中介绍的】,基本满足了我们实际业务中常用的需求,包括以下:
过滤器类型名称 |
实现的接口 |
默认的实现类 |
作用 |
执行的顺序与节点 |
---|---|---|---|---|
授权过滤器 |
IAuthorizationFilter |
AuthorizeAttribute |
用于限制进入控制器或控制器的某个行为方法 |
在控制器方法调用前执行,所有过滤器中最先执行的 |
动作过滤器 |
IActionFilter |
ActionFilterAttribute抽象类 |
用于进入动作方法之前或之后的处理 |
在控制器方法调用前/后执行 |
结果过滤器 |
IResultFilter |
ActionFilterAttribute抽象类 |
用于动作方法返回结果之前或之后的处理 |
在控制器方法调用完,跳转至view页面前/后执行 |
异常处理过滤器 |
IExceptionFilter |
HandleErrorAttribute |
用于处理某个动作方法或某个控制器里面抛出的异常 |
在控制器方法抛出异常时执行 |
Authentication【验证过滤器】 | IAuthenticationFilter | 在所有其他的过滤器或者Action方法之前执行 |
这四种类型的接口是MVC对过滤器的一个接口规范,同时MVC默认通过AuthorizeAttribute(授权)、HandleErrorAttribute(异常处理)、ActionFilterAttribute(动作和结果)三个类实现了这四个接口。
- ActionFilterAttribute类既实现了IActionFilter接口,也实现了IResultFilter接口,这是个抽象类,要求必须提供一个实现,所以一般都会通过继承ActionFilterAttribute类,实现自定义的过滤器。
- AuthorizeAttribute和HandleErrorAttribute类则包含了一些有用的特性,可以不必创建派生类进行使用。
- 除以上接口之外,我们还要用到FilterAttribute类,这个类将我们的过滤器包装成了特性,使我们的过滤器可以方便的在Action方法上方使用【在方法前添加特性】。
过滤器有以下几个特点:
-
可用于动作方法(Action)
-
可用于控制器(Controller)
-
可多个Filter同时使用
-
不同级别可以混搭
-
可运用于基类的过滤器,会影响该基类的所有派生类
授权过滤器
所有实现了IAuthorizationFilter接口的都可以称之为授权过滤器。它的接口定义如下:
namespace System.Web.Mvc { // // 摘要: // 定义授权筛选器所需的方法。 public interface IAuthorizationFilter { // // 摘要: // 在需要授权时调用。 // // 参数: // filterContext: // 筛选器上下文。 void OnAuthorization(AuthorizationContext filterContext); } }
授权过滤器是最先运行的过滤器,它运行在其它过滤器和Action方法之前。客户端请求在调用Action之前,MVC框架会检测Action上是否有授权过滤器,如果有会调用OnAuthorization方法,如果此方法批准了请求,才会调用相应的Action。流程如图:
过滤器类型 | 接口 | |
Authentication【验证过滤器】 | IAuthenticationFilter | 在所有其他的过滤器或者Action方法之前执行 |
Authorization【授权过滤器】 | IAuthorizationFilter | 在允许其他过滤器或者Action方法之前,执行 |
Action【Action过滤器】 | IActionFilter | 在Action方法之前或者之后执行 |
Result【结果过滤器】 | IResultFilter | 在Action方法的执行结果之前或者之后执行 |
Exception【异常过滤器】 | IExceptionFilter | 只有在其他过滤器,Action方法,或者Action的执行结果执行的时候出现异常,才会执行异常过滤器 |
ASP.NET 中的过滤器类型以及它们的执行顺序
1.Authentication Filters【验证过滤器】
Authentication 过滤器在任何其他过滤器或者Action方法之前执行。Authentication 过滤器确保你是合法还是非法用户。它实现了IAuthenticationFilter接口。
2.Authorization Filters【授权过滤器】
AuthorizeAttribute和RequireHttpsAttribute都是Authorizatio过滤器的例子。授权过滤器用来检查用户是否有访问权限。授权过滤器实现了IAuthorizationFilter接口。
3.Action Filters【Action过滤器】
Action过滤器是一个特性,你可以应用到控制器的方法上,也可以应用到整个控制器上。这个过滤器将会在Action方法开始执行之前或者开始执行之后执行,以及Action执行之后开始调用。
Action过滤器实现了IActionFilter接口,有两个方法OnActionExecuting和OnActionExecuted。OnActionExecuting在Action方法之前执行,并给了一个机会来取消执行Action方法。这些过滤器包含了一些逻辑,在Action方法执行之前或者执行之后调用,你可以使用Action过滤器,来修改控制器中的Action方法返回的视图数据。
4.Result Filters【结果过滤器】
OutputCacheAttribute类就是结果过滤器的一个例子。结果过滤器实现了IResultFilter接口。和IActionFilter类似,也有OnResultExecuting和OnResultExecuted两个方法。这些过滤器包含一些逻辑,在ViewResult开始执行之前或者之后调用。你可以使用结果过滤器,来修改视图的结果,在视图呈现到浏览器之前。
5.Exception Filters【异常过滤器】
HandleErrorAttribute类是ExceptionFilters的一个例子。异常过滤器实现了IExceptionFilter接口,异常过滤器在程序运行的过程中如果发生了未处理的异常就会执行。这些过滤器可以用做异常过滤器,用来处理控制器中的Action方法的错误,或者Action方法返回结果的错误。你可根据需要以重写这些方法。
好了,上面的理论知识介绍的差不多,我们来创建一个项目,练练手,实际操作一下:
1.在ASP.NET MVC 5中创建一个自定义的Authentication过滤器
创建一个MV项目:
在项目中,创建一个文件夹AuthData,添加我们自定义的类AuthAttribute;
IAuthenticationFilter接口定义了两个方法:OnAuthentication和OnAuthenticationChallenge。OnAuthentication先执行,用来处理需要的验证逻辑。OnAuthenticationChallenge用来根据用户验证的结果,进一步做限制处理。在OnAuthentication方法中,我写了一些代码用来对用户作验证,OnAuthenticationChallenge中,我写了一些代码,用来执行其他任务。
现在,让我们来测试一下,我们写的自定义验证过滤器;
运行项目,然后注册:
你还可以管理你的账户信息:
2.现在看看 Authorization Filter:
Authorization确保只有经过允许的用户才能访问。这些过滤器在Action方法执行之前调用,实现了IAuthorizationFilter接口。包含了一个方法OnAuthorization。
为了验证Authorization,我们对刚才的AuthAttribute类作个修改。我们重写了AuthorizeAttribute类中的AuthorizeCore(HttpContextBase httpContext)方法。
现在打开Home控制器,修改代码:
运行项目:输入刚才注册的账号和密码:可以看到授权通过,登录成功了。
还可以这样:在About方法上标识特性,然后允许项目,点击关于按钮,就会弹出来登录页面,让登录:
还可以限制,只让某个用户看到About页面,可以这样做:这里,我只让649713412@qq.com这个用户访问About页面。
现在我们运行项目,重新注册一个账号123456@qq.com.
可以看到,123456@qq.com这个账号访问不了About页面。又弹出来了登录页面。
3.再来看看Action Filter,又下面的几个Action Filters:
- Output Cache:缓存控制器的Action
- Handle Error:当控制器的方法报错的时候,处理错误
- Authorize :允许你限制有相应权限的才能访问
Output Cache
下面的例子,指定返回值将会被缓存5秒
再看看Handle Error例子:
为了实现Handle例子,我们改装一下AuthAttribute类:
注意我们需要创建一个静态的错误页面:
然后运行项目,在地址栏输入:
然后就看到了:错误页面》》
输入大于100的试试:
好了 ,以上就是Filters的全部内容,有不明白的,欢迎留言。目前这个0基础系列,暂时先告一段落,我打算写一些高级的内容,后续如果有基础的知识需要讲,就接着这个系列写。谢谢大家支持。