西西软件园多重安全检测下载网站、值得信赖的软件下载站!
软件
软件
文章
搜索

首页编程开发ASP.NET → ASP.Net MVC不在多个Action上写同样的FitlerAttribute

ASP.Net MVC不在多个Action上写同样的FitlerAttribute

相关软件相关文章发表评论 来源:本站整理时间:2010/12/8 21:26:52字体大小:A-A+

作者:佚名点击:130次评论:0次标签: 异常处理 Action执行器 Controller

PeStudio编程辅助v8.42 绿色免费版
  • 类型:编程辅助大小:699KB语言:英文 评分:5.0
  • 标签:
立即下载
 以AuthorizeAttribute这个Filter举例,一个Controller有若干个Action,包括登录的Action(如Login)。这时我们就不能将Authorize放在Controller签名之上,不得不给除了Login这个Action之外的所有Action加上个Authorize——这也不是大不了的事情,我多写几个Authorize也觉得没关系,或者我重新实现一个IAuthorizationFilter,在里面判断如果是Login这个Action,就不进行验证。

如果我想给所有Action注入一段html到页面底部,我必须去修改Controller吗?
如果我想动态控制某个Action允许由哪些角色访问,我通过修改Controller能实现吗?
如果我想这时候控制的由哪些角色来访问,需求改变时我想要控制由哪些用户来访问呢?我还得去修改Controller吗?或者增加或修改Filter吗?

所以需求就出现了:能不能让我集中管理这些Filter,并且控制的更灵活呢?能让所有Controller和Action签名上都干干净净的那就最好了。

那就把Filter放在一处集中管理,在Action或ActionResult等执行Filter之前保证将需要的Filter准备好就行了。

在解决问题之前,先简单回顾一下Action执行前后发生的事。

我们知道,在ASP.NET MVC中,每一次请求通常都定位到一个具体的Controller的Action中。
在默认情况下,由Action执行器ControllerActionInvoker类去控制Action的执行(或不执行),实际做事的是InvokeAction方法。
InvokeAction方法首先去查找Action(由FindAction方法),如果Action被找到了,会去检索该Action拥有的Filter以及该Action所属Controller的Filter(由GetFilters方法),将找到的所有Filter放入一个FilterInfo变量中,FilterInfo中保存的Filter不完全是Action是自己的。然后先执行找到的所有IAuthorizationFilter(由InvokeAuthorizationFilters方法)。当然,在InvokeAuthorizationFilters方法中,只要有IAuthorizationFilter的ActionResult不为null就会返回不会执行其他的了。 InvokeAction方法检测执行结果,如果ActionResult的确不为空,则执行该Result,其他Filter就不管啦。 接着获取要传给Action的参数集(交给GetParameterValue方法),就执行InvokeActionMethodWithFilters方法,方法名已经足够说明它是干什么的了。如果一切正常,根据InvokeActionMethodWithFilters方法返回的结果去接着就执行InvokeActionResultWithFilters方法。在执行InvokeAuthorizationFilters一直到执行InvokeActionResultWithFilters的这一整个过程中如果发生异常,则根据捕获的异常执行InvokeExceptionFilters进行异常处理。

这里需要注意一点:InvokeAction、GetFilters、InvokeAuthorizationFilters、GetParameterValue、InvokeActionMethodWithFilters、InvokeActionResultWithFilters、InvokeExceptionFilters等全是虚方法,除非有足够的原因去继承IActionInvoker重写一个Action执行器,否则重写某些方法足够扩展。

甚至ControllerActionInvoker类本身,在ASP.NET MVC基础架构中也是可以替换的,怎么替换呢?继承Controller类时重写CreateActionInvoker方法就可以。

另外还可以在构造Controller对象给它的ActionInvoker属性赋值,这又怎么赋值?重写DefaultControllerFactory创建Controller实例的GetControllerInstance方法。 然后在Applicaion_Start中设置新的ControllerFactor:
ControllerBuilder.Current.SetControllerFactory(new YourControllerFactory());

回到主题。 首先我们将Filter和Action的对应关系(Filter和Controller的对应关系在本文中暂不讨论)存于一个集合中并缓存起来。

从找到Action到执行InvokeAuthorizationFilters之前,必须将IAuthorizationFilter准备好;从找到Action到执行InvokeActionMethodWithFilters之前,必须将Action需要的IActionFilter准备好;从找到Action到执行InvokeActionResultWithFilters之前,必须将ActionResult需要的IResultFilter准备好。异常发生InvokeExceptionFilters执行之前,必须将IExceptionFilter准备好。 基于以上几点,我们好像只能在FindAction方法和GetFilters方法之间选择一个。当然也就是只有GetFilters了。

在Filter方法中,我们根据当前Action的特征(如方法名,或包括请求方式Get或Post)与Filter和Action对应表。将匹配的Filter加进FilterInfo变量中。

    相关评论

    阅读本文后您有什么感想? 已有人给出评价!

    • 8 喜欢喜欢
    • 3 顶
    • 1 难过难过
    • 5 囧
    • 3 围观围观
    • 2 无聊无聊

    热门评论

    最新评论

    第 2 楼 四川成都铁通ADSL 网友 客人 发表于: 2011/7/21 13:15:23
    撒旦法撒旦法撒旦法第三方

    支持( 0 ) 盖楼(回复)

    第 1 楼 广东广州番禺电信 网友 客人 发表于: 2010/12/30 1:48:16

    支持( 0 ) 盖楼(回复)

    发表评论 查看所有评论(0)

    昵称:
    表情: 高兴 可 汗 我不要 害羞 好 下下下 送花 屎 亲亲
    字数: 0/500 (您的评论需要经过审核才能显示)