一、过滤器简介
1.1、理解什么是过滤器
1、过滤器(Filters)就是向请求处理管道中注入额外的逻辑。提供了一个简单而优雅的方式来实现横切关注点。
2、所谓的过滤器(Filters),MVC框架里面的过滤器完全不同于ASP.NET平台里面的Request.Filters和Response.Filter对象,它们主要是实现请求和响应流的传输。通常我们所说的过滤器是指MVC框架里面的过滤器。
3、过滤器可以注入一些代码逻辑到请求处理管道中,是基于C#的Attribute的实现。当负责调用Action的类ControllerActionInvoker在调用执行Action的时候会检查Action上面的Attribute并查看这些Attribute是否实现了指定的接口,以便进行额外的代码注入处理
1.2、理解为什么要使用过滤器
假设你做了一个小项目,其中某个功能是操作管理用户信息模块,有这样一个需求,对用户信息管理必须是已通过认证的用户才能操作,我们可以在每一个Action方法里面检查认证请求,如下所示:
using MvcFilterDmo.Core; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Security; namespace MvcFilterDmo.Controllers { public class HomeController : Controller { public ActionResult Index() { if (!Request.IsAuthenticated) { FormsAuthentication.RedirectToLoginPage(); } //操作部分... return View(); } public ActionResult Insert() { if (!Request.IsAuthenticated) { FormsAuthentication.RedirectToLoginPage(); } //操作部分... return View(); } public ActionResult Update() { if (!Request.IsAuthenticated) { FormsAuthentication.RedirectToLoginPage(); } //操作部分... return View(); } public ActionResult Delete() { if (!Request.IsAuthenticated) { FormsAuthentication.RedirectToLoginPage(); } //操作部分... return View(); } //其他Action操作方法 //... } }</div>
通过上面的代码,可以发现使用这种方式检查请求认证有许多重复的地方,这也就是为什么要使用过滤器的原因,使用过滤器可以实现相同的效果。如下所示:
using MvcFilterDmo.Core; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Security; namespace MvcFilterDmo.Controllers { [Authorize] public class HomeController : Controller { public ActionResult Index() { //操作部分... return View(); } public ActionResult Insert() { //操作部分... return View(); } public ActionResult Edit() { //操作部分... return View(); } public ActionResult Delete() { //操作部分... return View(); } //其他Action操作方法 //... } }</div>
过滤器是.NET里面的特性(Attributes),它提供了添加到请求处理管道的额外方法。这里使用Authorize过滤器可以实现同样的效果,不过代码就显然比之前更加简洁优雅。
二、过滤器的使用
2.1、基本类型的过滤器
过滤器实现的机制:在MVC框架调用一个Action之前,它会检查方法的定义中是否实现了特性(Attributes),如果实现的话,那么在请求处理管道适当的位置,该特性定义的方法会被调用。
ActionFilterAttribute类既实现了IactionFilter接口,也实现IResultFilter接口。这是一个抽象类,它要求你必须提供一个实现。AuthorizeAttribute和HandleErrorAttribute类,则包含了一些有用的特性,并且可以不必创建派生类进行使用。
2.2、过滤器的应用、应用方式以及执行顺序
应用: 过滤器可以被应用到控制器上也可以用到Action方法上,应用到控制上时,表示所有的Action方法都有了这个过滤器,并且可以混合使用,或多次使用,如下所示:
[A] //表示所有的Action方法都会应用A过滤器 Public class DemoController:Controller { [B]//B,C过滤器只作用于此Action方法,但它也会有A过滤器的应用效果 [C] Public ActionResult Index() { //操作部分... return View(); } }</div>
应用方式:特性的方式,如上面代码所示。
执行顺序:相同类型过滤器,执行顺序靠近方法的先执行,不同类型的过滤器一般执行顺序为【authorize--->action--->actionResult】至于异常过滤器不分先后,只要抛出异常时就会执行异常过滤器。如果要调整执行顺序,可以通过调整Order方法值大小来控制执行顺序,值越小,越先执行。下图是Action/Result过滤器应用的执行顺序图
(1)、相同类型过滤器应用示例:两个自定义Action过滤器MyFirstFilter,MyThreeFilter应用到同一个Action方法Index上。
Three控制器代码如下:
MyFirstFilter 代码如下:
MyThreeFilter代码如下:
运行结果如下:
(2)、不同类型过滤器应用示例:有一个自定义Action过滤器MyFirstFilter,有一个自定义Result过滤器MySecondFilter,应用到同一个Action方法Index上。
Three控制器代码如下:
MyFirstFilter 代码如下:
MySecondFilter代码如下:
运行结果如下:
看完上面的解释,可能你现在对这些过滤器的执行顺序,以及如何自定义过滤器还不明白,不要紧,下面我们会逐一介绍这几个基本的过滤器的使用,以及如何自定义过滤器。
2.3、使用授权过滤器
所有实现了IAuthorizationFilter接口的都可以称之为授权过滤器:其定义如下:
public interface IAuthorizationFilter { void OnAuthorization(AuthorizationContext filterContext); }</div>
由于MVC框架系统自带的AuthorizeAttribute实现有一些突出的功能,而这种牵涉到安全的代码一定要谨慎的编写,所以一般我们不会直接实现这个接口,而是去继承AuthorizeAttribute这个类,并重写其AuthorizeCore方法,签名为: bool AuthorizeCore(HttpContextBase httpContext) 而处理授权失败的时候,可以重写其HandleUnauthorizedRequest方法,其签名为: void HandleUnauthorizedRequest(AuthorizationContext context) 。注意:验证与授权是两回事,验证发生在授权之前。
默认的授权过滤器已经有了验证的功能,其验证的机理是利用Asp.net平台自带的验证机制,如表单验证和Windows验证。除了验证功能,它本身还有授权的功能。授权过滤器是所有过滤器中最早运行的。
经过Route到达了控制器的时候,在调用Action之前,MVC框架会检测在相关的Action上是否有授权过滤器,如果有会调用OnAuthorization方法,如果此方法批准了请求,才会调用相应的Action。
使用授权过滤器几种情况如下:
1.直接在Action上或者控制器上加Authorize,表示启用了验证,但不牵涉到授权。
2.添加Authorize(Users=“a,b”)],表示启用了验证,并且也启用了授权,只有a或者b用户能访问此控制器。
3.当添加Authorize(Roles=“admin,Member”)]时的步骤如下:
---利用asp.net自带的角色提供者,或者实现自己的角色提供者,实现自己的角色提供者时,只需要集成RoleProvider类型,并实现其中的所有方法