第9讲 使用Filter特性

2010.9.9 苏鹏

内容介绍

-基本Filter的使用

-自定义开发Filter

 

预备知识

-安装Visual Studio 2010 Express

-了解ASP.Net

-了解设计模式基本概念

 

Filter的作用

-对Action的附加说明

 

ASP.Net MVC中的Filter

-Authorize

ASP.Net里面也有授权管理,它是用Membership来做的,绑定每个文件的Url。这里MVC的授权是在Action访问之前要求用户名和密码,证明您是具有相应操作权限的

-HandleError

Action中会抛出异常,HandleError加上之后就能处理这个异常

-OutputCache

缓存输出的内容

-RequireHttps

这也是授权,但是要求更严格,网络上传输的请求很多都是Http,即超文本传输协议,它传输的文本是明文的,它顶多做点Encode是把一些字符转义一下,不会对数据进行加密,这样是很不安全的。现在网络的Sniffer技术已经很流行了,任何人只要在网桥上架一个监听器,都能听到你相应的流量。如果对流量进行分析,就能看到流量里的内容。所以对于一些高安全性要求的网络,例如网络银行等,都是用Https进行传输,s的意思是传输在SSL层上,SSL层是传输的一个加密协议,它保证传输过程当中,双方使用一种保密机制来进行传输,而不会被第三方监听到,即使监听到也分析不明白,全部是乱码。所以Https有效地避免了传输数据被监听的情况。RequireHttps标签,它就会要求你,一旦使用这个标签,数据传输一定必须得是Https进行的。如果是Http的,那就会有一些处理策略。

 

Authorize

-AuthorizeAttribute标签

image

在ASP.Net 2.0时代,我们为了让用户使用角色和权限管理,微软提供了一套针对用户角色和权限管理的架构,即Membership。这个核心部分有几部分,第一部分有一大堆Membership对应的控件,这些控件能帮助您创建用户、登录、显示用户登录状态等等。第二部分有一堆Service的API,隶属于Membership命名空间下,它能创建用户、查看用户是否登录、验证用户是否属于某一权限。最底层,它有一个数据库,里面有5个表,其中有角色Roles(每一不同角色针对不同文件夹访问)、用户Users(每个Users隶属于一个角色,Users有登录信息),这5个表保存了权限管理的数据。这个Service依然在今天MVC架构中可以使用。这就是今天的AuthorizeAttribute标签。标签中的Roles就是验证登陆的角色名,这个例子表名只有角色名叫Admins和SuperAdmins的用户可以访问。如果是用户名验证,可以写Users="XXX,XXX"(用逗号分隔)。只有指定的名称的属性才能访问到。

这和以前ASP.Net WebForm的Membership用法有所不同。假如有一些页面是只有Admin用户能操作的,那我们就创建一个叫Admin的文件夹,接下来把用户操作文件全部放到Admin文件夹下面。用户想要访问这些文件的时候,就必须要通过权限认定。对每一文件夹的定义Rules写在Webconfig里边。

MVC架构下就无法复用这种策略,为什么呢?想想MVC架构的基础概念。每一个请求现在对应的已经不再是

一个文件了,它对应的是个Action。这就使得我们指定一个文件夹下的文件的方式不合适了。所以针对不同用户,我们要限制和管理的只不过是他们的一个操作。这个操作最小粒度就是一个函数,即Action。这样把权限和用户操作挂钩,而不是文件,反而更有效。

image

上面的例子中,如果要使用DeleteAllUsers方法,必须首先具有Admins或SuoerAdmins的角色,通过AdminController的权限,然后还需要是名叫Phil的用户,才能访问这个Action。这个逻辑关系实际上是一种叠加的逻辑关系。

如果只写了Authorize的标签,没有写后面的条件,那就说明这只是登录授权,只要用户登录就可以访问Action。如果是没登陆想访问带有Authorize标签的方法,会返回一个401错误,它在IIS里面的意思就是您所访问的资源未经授权。当然,同ASP.Net WebForm一样,MVC架构中这种未授权的情况也可以让用户跳转到一个登陆页面。

 

RequireHttps

image

这个标签要求请求必须是Https。它既可以放在Controller上,也可以放在Action上。RequireHttps标签的Action被访问的时候,要求必须使用SSL来进行解析,如果有一个不是使用SSL的请求发过来的时候,就要分情况讨论了,如果是Get请求,那么我们自动会把协议变成Https的,然后接着访问。但要注意,您的Web服务器还必须得支持Https,如果它把协议变成了Https,但是您的服务器不支持Https,那一样是报告404错误的。如果是Post请求,那么是没法加密Post里面的信息的,因此会抛出异常。

 

OutputCache

-CacheProfile

指定Cache名字,这个名字可以写在Filter上,也可以写在Web.config上。写在Web.config上就可以复用OutputCache的规则

-Duration

指定缓存释放时间,单位秒

-Location

默认情况是Any

-NoStore

表示不缓存结果

-SqlDependency

指定缓存是根据某一SQL Server指定的某一表的值来缓存的,当值改变的时候缓存释放,当值没变的时候一直缓存

-VaryByContentEncoding

它是用一个逗号分隔的字符串说明缓存所用的编码格式

-VaryByCustom

是否缓存取决于调用GetValueByCustomString这个函数。这个函数是在Global.asax.cs里的,你在这里重载它的GetValueByCustomString函数,就能自己定制缓存

-VaryHeader

它是取决于Http请求的信息做缓存释放,你可以使用不同的方式来请求同一个Action来实现缓存的释放

-VaryByParam

根据参数释放缓存

image

在Action上写OutputCache标记之后,当请求发到Controller,Controller执行ActionInvoker找到Action的时候,说:你,准备起来干活了!Action说我不用干啊,你看我这有OutputCache标记呢,释放时间还没到呢,你去View层直接把缓存结果放回去就完事。这样就避免了性能的额外开销。

 

OutputCache在Web.config里面的配置

image

 

Exception Filter

image

它是指定一个Action去处理你的异常,并且指定一个View视图来指定显示你的异常。

如果是没有Handle异常,那么就不能正确的通过视图返回结果给用户,就会发生很多奇怪的事情,例如一运行就会报错,而错误出处和信息都不知道。

需要注意的是,异常捕获的定义需要从小到大地写,你要细分地每一个都写出来。它们的调用顺序是Order1先调用,Order2后调用。如果不写Order调用的顺序是未知的,不是谁写在上面谁先调用。应该尽量把大的异常的Order写的靠后。

在默认Debug运行下Filter不会捕获这个异常。因为Debug模式如果有异常直接抛给编译器了,这个标签就不起作用。

 

Custom Filters

image

要写自定义Filter,首先要继承自FilterAttribute类,然后要实现上面4个接口中的一个。其中ActionFilter和ResultFilter最常用,一个是专门在Action执行前执行中做操作的,一个是执行后返回前做操作的。

 

ActionFilterAttribute

image

 

ActionExecutingContext

它有两个参数:

-ActionParameters

它是一个字典类,它主要用来传递给Action的参数

-Result

在当前请求被取消的时候,Filter会自己生成一个ActionResult来代替从Action传过来的结果,把它传给用户

 

ActionExecutedContext

它有四个属性:

-Canceled

它是布尔值,如果设为True,Action请求就被取消,直接就会构造一个Result,给ActionExecutedContext里的Result,直接返回。

-Exception

它是抛出异常的支持情况

-ExceptionHandled

它是一个布尔值,可以把它设为True来撤销已经返回的Result。一旦它设为True,抛出异常,所有的Action都拿不到这个ActionResult结果,这个Result就永远丢失了

-Result

Action的返回结果

 

ResultExecutingContext

-Cancel

-Result

 

ResultExecutedContext

-Canceled

-Exception

-ExceptionHandled

-Result

 

编写ActionFilter

image

这里StopWatch之所以用ViewData存放而不是用全局的变量存放,是因为全局变量会对性能有一定影响。还不如把数据交给Action,因为反正Controller都会把数据给Action。

image

 

Filter执行顺序

-1.Order小的先执行

-2.具有同样Order的,看定义范围

-3.无Order的最后执行

-4.代码内部定义的(自己定义的Filter)优先执行

-5.同类型的Filter无法确定执行顺序

 

总结

-基本Filter的使用

-自定义开发Filter

2010.10.2

posted @ 2010-10-02 22:51  山天大畜  阅读(1448)  评论(0编辑  收藏  举报