Mvc的过滤器是特性类,可以使我们在执行Action之前,执行Action之后,执行Action发生异常时,编写相关的处理代码实现某些逻辑。下面是四个基本的Filter接口。

上面这四个基本的Filter接口又被其他类所继承实现。框架图如下:

可以发现具体的Filter类,如ActionFilterAttribute或者AuthorizeAttribute除了各自实现基本接口IActionFilter和IAuthorizationFilter之外还继承抽象类FilterAttribute,而后者又继承自Attribute类。FilterAttribute除了一个protected的构造函数之外还有一个int类型的Order属性,当在一Controller或者Action上面添加多个相同类型的Filter时定义Filter触发的顺序。ActionFilterAttribute同时继承实现了IActionFilter和IResultFilter接口,这两个接口的函数都实现为abstract函数。如果继承ActionFilterAttribute意味着可以在Action执行之前,之后,Action结果执行之前,之后编写相应的处理代码。

当在一个Action上面定义多个Filter时,如下面的代码。也可以以使用Order属性来控制执行顺序。在编码的过程中发现一个比较蛋疼的问题,就是特性的AllowMultiple会影响到执行顺序和异常抛出时的处理。但是在Mvc的InvokeActionMethodWithFilters源码里面并没有发现对于AllowMultiple的特殊处理呀?奇怪!

[FirstFilter]
[SecondFilter]
public ActionResult Index(string id, string other)
{ ViewData["Message"] = "欢迎使用 ASP.NET MVC!";
ViewData["id"] = id;
ViewData["other"] = other;
return View();
}
/*
First OnActionExecuting
Second OnActionExecuting
Second OnActionExecuted
First OnActionExecuted
First OnResultExecuting
Second OnResultExecuting
Second OnResultExecuted
First OnResultExecuted
*/
/**************** 当吧FirstFilter定义为AllowMultiple = true时的执行顺序是这样的
Second OnActionExecuting
First OnActionExecuting
First OnActionExecuted
Second OnActionExecuted
Second OnResultExecuting
First OnResultExecuting
First OnResultExecuted
Second OnResultExecuted
****************/
/* 当在Second OnActionExecuting中抛出异常时,
* 将会跳到First OnActionExecuted ,Second OnActionExecuted不会执行
* 但是如果FirstFilterAttribute的AllowMultiple = true,异常将不会被拦截,直接抛出
First OnActionExecuting
Second OnActionExecuting
First OnActionExecuted
First OnResultExecuting
Second OnResultExecuting
Second OnResultExecuted
First OnResultExecuted
*/

Controller下的Filter

       Controller类除了继承自ControllerBase类之外,还继承了四个基本的Filter接口,这也就意味着同样可以在Controller类里面来定义实现相关方法来实现过滤器的功能,这里有一点需要注意就是Controller里面定义的Filter方法优先级最高,并且不受附加在Controller或者Action之上的Filter的Order影响。These controller filter methods give you a very quick and easy way to add controller code that runs before or after all action methods on that particular controller, or whenever an unhandled exception occurs in that particular controller. 什么时候使用Controller继承自接口的Filter,什么时候自定义一个Filter然后附加在方法之上,这要看情况,当过滤器的方法只是针对某个特殊的Controller时,就使用前者,当过滤器需要被多个Controller公用时,就使用后者。

Authorization Filters

       authorization filters 是一个特殊的过滤器,他会在所有其他类型的过滤器触发前被触发。其重要属性如下:

public class MicrosoftController : Controller
{
[Authorize(Users="billg, steveb, rayo", Roles="chairman, ceo")]
public ActionResult BuySmallCompany(string companyName, double price
{
// Cher-ching!
}
}

通过上面的定义将使BuySmallCompany只能被用户名为"billg,steven,rayo"之一,角色为"chairman,ceo"之一的访问者访问到(角色和用户名需为"与关系",就是两个必须都符合,不能是"或关系",即只符合其中一项)。如果用户名或者角色不符合将会被设置为Http状态为401,也就是验证失败的状态,这个401状态将会激活项目中启用的验证系统(如Form验证)自动跳转到登陆页面或者显示一个认证失败的页面。Authorization Filters是根据HttpContext.User来判断用户名和角色的。因此可以同Form验证结合。具体怎么结合还需要另外研究。

          在使用Mvc Authorization Filters的时候还需要注意一点。就是当项目中结合使用Output Caching时。在缓存项没有被改变的情况下,action的调用的结果是放在缓存中的,在第一次被被访问时直接将这个结果输出给客户端浏览器,不用在触发调用action,因此action的filter也就不会被调用了。这也就意味着会有这么一种情况,经过授权的用户访问某个action,在这个用户访问之后action的结果被缓存下来,接下来未经授权的用户也可以访问这个action。漏洞就来了!微软Mvc团队有意识到这一点,在缓存输出前还是会调用Authorization Filters再验证一次。这也就意味当在自定义定义Authorization Filters时,最好时继承自Authorization Filters,而不是继承自FilterAttribute和 IAuthorizationFilter。以防止在使用缓存时,出现了安全漏洞。

MVC系统学习6—Filter的更多相关文章

  1. MVC系统学习1—MVC执行流程

    用MVC来做开发也有一段时间了,但是感觉一直没入门,就徘徊在似懂非懂的层次,和去年刚毕业学习WebForm时一样,当时通过张子阳老兄的几篇文章,明白了请求处理流程,页面生命周期才真正明白了WebFor ...

  2. MVC系统学习5——验证

    其实关于Mvc的验证在上一篇已经有讲过一些了,可以通过在我们定义的Model上面添加相应的System.ComponentModel.DataAnnotations空间下的验证属性.在服务器端通过Mo ...

  3. MVC系统学习2—MVC路由

    在MVC下不是通过对物理文件的映射来实行访问的,而是通过定义后的路由Url来实现访问的.在前一篇讲到我们是在全局文件下进行路由配置. routes.MapRoute(                & ...

  4. MVC系统学习3—ModelBinder

    在ASP.NET MVC中,每个请求都被映射到一个Action方法,我们可以在action的方法中定义相应类型的参数,View中通过post.get方式提交的request参数,只要名称一致就会对应到 ...

  5. Mvc系统学习9——Areas学习

    在Mvc2.0中,新增加了一个特性就是Areas.在没有有使用Areas的情况下,我们的Mvc项目组织是下面这样的.当项目庞大的时候,Controllers,Model,View文件下下面势必会有很多 ...

  6. MVC系统学习7—Action的选择过程

    在Mvc源码的ControllerActionInvoker的InvokeAction方法里面有一个FindAction方法,FindAction方法在ControllerDescriptor里面定义 ...

  7. MVC系统学习4—ModelMetaData

    在Mvc R2中,新引入了一些扩展方法,如后面带一个for的方法,这些扩展方法会根据Model的属性自定生成相应的Html元素,如Html.EditFor(Model=>Model.IsAppr ...

  8. MVC系统学习8——AsyncController

    关于为什么使用异步Controller,这里不做备忘,三岁小孩都懂.主要的备忘是如何使用AsyncController. //这个action以Async结尾,并且返回值是void public vo ...

  9. ASP.NET MVC学习笔记-----Filter

    ASP.NET MVC学习笔记-----Filter(1) Filter类型 接口 MVC的默认实现 Description Authorization IAuthorizationFilter Au ...

随机推荐

  1. 题解报告:hdu 1398 Square Coins(母函数或dp)

    Problem Description People in Silverland use square coins. Not only they have square shapes but also ...

  2. 464 Can I Win 我能赢吗

    详见:https://leetcode.com/problems/can-i-win/description/ C++: class Solution { public: bool canIWin(i ...

  3. Stamus Networks的产品SELKS(Suricata IDPS、Elasticsearch 、Logstash 、Kibana 和 Scirius )的下载和安装(带桌面版和不带桌面版)(图文详解)

    不多说,直接上干货!  SELKS是什么? SELKS 是Stamus Networks的产品,它是基于Debian的自启动运行发行,面向网络安全管理.它基于自己的图形规则管理器提供一套完整的.易于使 ...

  4. [转]C#Linq中的Union All/Union/Intersect和Top/Bottom和Paging和SqlMethods,skip,take,takewhile,skipwhile,编译查询等

    本文转自:http://www.cnblogs.com/suizhikuo/p/3791799.html 我们继续讲解LINQ to SQL语句,这篇我们来讨论Union All/Union/Inte ...

  5. tuple元组创建单元素

    创建tuple单元素,一定要在结尾时添加一个逗号(,)解:如果不加逗号,哪怕是使用tuple()正确的创建元组,也会有歧义,它会把创建tuple元组的单元素,当成一个普通的输出语句结果列:如下,错误的 ...

  6. Linux 之 2>&1

    我们在Linux下经常会碰到nohup command>/dev/null 2>&1 &这样形式的命令.首先我们把这条命令大概分解下首先就是一个nohup表示当前用户和系统 ...

  7. 关于Android软键盘把布局顶上去的问题(一)

    最近接触到了一个登陆页面,布局最上面显示的是一个波纹的view,中间显示账号和密码的EditText,紧接着还有一个Button: 希望:点击EditText时,软键盘不能把波纹的view顶出去,也不 ...

  8. TCP/UDP套接字 java socket编程实例

    网络协议七层结构: 什么是Socket? socket(套接字)是两个程序之间通过双向信道进行数据交换的端,可以理解为接口.使用socket编程也称为网络编程,socket只是接口并不是网络通信协议. ...

  9. iOS Programming Camera 2

    iOS Programming Camera  2  1.1 Creating BNRImageStore The image store will fetch and cache the image ...

  10. jQuery 冒泡事件

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...