【转】Asp.Net MVC3 简单入门详解过滤器Filter

原文地址:http://www.cnblogs.com/boruipower/archive/2012/11/18/2775924.html

前言

在开发大项目的时候总会有相关的AOP面向切面编程的组件,而MVC(特指:Asp.Net MVC,以下皆同)项目中不想让MVC开发人员去关心和写类似身份验证,日志,异常,行为截取等这部分重复的代码,那我们可以通过AOP截取实现,而在MVC项目中我们就可以直接使用它提供的Filter的特性帮我们解决,不用自己实现复杂的AOP了。

在Asp.net Mvc中当你有以下及类似以下需求时你可以使用Filter功能

  1. 判断登录与否或用户权限
  2. 决策输出缓存
  3. 防盗链
  4. 防蜘蛛
  5. 本地化与国际化设置
  6. 实现动态Action

第一节:知识储备

Asp.Net MVC提供了以下几种默认的Filter:


Filter Type


实现接口


执行时间


Default Implementation


Authorization filter


IAuthorizationFilter


在所有Filter和Action执行之前执行


AuthorizeAttribute


Action filter


IActionFilter


分别在Action执行之前和之后执行。


ActionFilterAttribute


Result filter


IResultFilter


分别在Action Result执行之后和之前


ResultFilterAttribute


Exception filter


IExceptionFilter


只有在filter,

或者 action method, 或者 action result 抛出一个异常时候执行


HandleErrorAttribute

大家注意一点,Asp.Net MVC提供的ActionFilterAttribute默认实现了IActionFilter和IResultFilter。而ActionFilterAttribute是一个Abstract的类型,所以不能直接使用,因为它不能实例化,所以我们想使用它必须继承一下它然后才能使用。

Filter继承于ActionFilterAttribute抽象类,并可以覆写 void OnActionExecuting(ActionExecutingContext) 和 void OnActionExecuted(ActionExecutedContext) 以及 void OnResultExecuting(ResultExecutingContext)和 void OnResultExecuted(ResultExecutedContext)。

它们的执行先后顺序如下:

  OnActionExecuting是Action执行前的操作

  OnActionExecuted则是Action执行后的操作

  OnResultExecuting是解析ActionResult前执行

  OnResultExecuted是解析ActionResult后执行

接下来我们只要对以上的方法进行重写就可以在相应的步骤做一些操作了。

第二节:Filter实战

光说不练假把式,下面我给大家一个示例,来看看它们的执行顺序

首先添加一个普通的类,这个类要继承ActionFilterAttribute,,直接上代码了

   public class TestFilterAttribute:ActionFilterAttribute
    {
        public string Message { get; set; }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
            filterContext.HttpContext.Response.Write("Action执行之前"+Message+"<br />");
        }

        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            base.OnActionExecuted(filterContext);
            filterContext.HttpContext.Response.Write("Action执行之后"+Message+"<br />");
        }

        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            base.OnResultExecuting(filterContext);
            filterContext.HttpContext.Response.Write("返回Result之前"+Message+"<br />");
        }

        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            base.OnResultExecuted(filterContext);
            filterContext.HttpContext.Response.Write("返回Result之后"+Message+"<br />");
        }
    }

写完这个代码后,我们回到Action上,打上上面的标记如下所示:

     [TestFilter(Message="Action")]
        public ActionResult Index()
        {
            HttpContext.Response.Write("Action正在执行···<br />");
            return Content("正在返回Result···<br />");
        }

然后通过浏览器访问上面的Action便可以看到下面的执行顺序

总的执行顺序是:

Action执行前:OnActionExecuting方法先执行→Action执行→OnActionExecuted方法执行→OnResultExecuting方法执行→返回的ActionRsult中的executeResult方法执行→OnResultExecuted执行。最终显示的效果就是如上图所示。

感觉很爽吧!呵呵!这要想用到这个过滤机制的地方的时候,只要在Action上面添加标记便可以实现效果。

如果我们将此标签打到Controller上的话,TestFilterAttributeFilter将作用到Controller下的所有的Action。例如如下代码所示:

  [TestFilter(Message="Controller")]
    public class TestFilterController : Controller
    {
        //
        // GET: /TestFilter/
        [TestFilter(Message="Action")]
        public ActionResult Index()
        {
            HttpContext.Response.Write("Action正在执行···<br />");
            return Content("正在返回Result···<br />");
        }

    }

如果单纯的按照上面的代码来做就有个问题了我们再执行显示的页面会有什么情况呢?Controller上的Filter会执行吗?那标签的作用会执行两次吗?下面是最后的执行结果如下图所示:

结果说明:默认情况下Action上打了TestFilterAttribute 标签后,虽然在Controller上也打上了此标签,但它只有Action上的标签起作用了。

补充:如果Action没有打上TestFilterAttribute标签,那么Controller上的标签便会被执行。

Index 执行时,Filter的方法只执行了一次,而某些情况下我们也想让Controller上的FilterAttribute也执行一次TestFilterAttribute,那我们怎么才能让Controller上的[TestFilter(Message = "controller")]也起作用呢?

答案是:我们只需在TestFilterAttribute类的定义上打上标记[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]即可【下面类的最上面红色字体部分】,也就是让其成为可以多次执行的Action代码如下:

  [AttributeUsage(AttributeTargets.All,AllowMultiple = true)]
    public class TestFilterAttribute:ActionFilterAttribute
    {
        public string Message { get; set; }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
            filterContext.HttpContext.Response.Write("Action执行之前"+Message+"<br />");
        }

        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            base.OnActionExecuted(filterContext);
            filterContext.HttpContext.Response.Write("Action执行之后"+Message+"<br />");
        }

        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            base.OnResultExecuting(filterContext);
            filterContext.HttpContext.Response.Write("返回Result之前"+Message+"<br />");
        }

        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            base.OnResultExecuted(filterContext);
            filterContext.HttpContext.Response.Write("返回Result之后"+Message+"<br />");
        }
    }

浏览效果如下图:

我们看到的结果是Controller上的ActionFilter先于Action上打的标记执行。同样Result执行executeResult方法之前也是先执行Controller上的Filter标记中的OnResultexecuteing方法。

最后的执行顺序是:Controller上的OnActionExecuting→Action上的OnActionExecuting→Action执行→Action上的OnActionExecuted→Controller上的OnActionExecuted 

到此Action就执行完毕了,我们看到是一个入栈出栈的顺序。后面是Action返回ActionResult后执行了ExecuteResult方法,但在执行之前要执行Filter。具体顺序为:

接上面→Controller的OnResultExecuting方法→Action上的OnResultExecuting→Action返回ActionResult后执行了ExecuteResult方法→Action上的OnResultExecuted执行→Controller上的OnResultExecuted执行→结束。

 

又接着一个问题也来了,我们想有些公共的方法需要每个Action都执行以下,而在所有的Controller打标记是很痛苦的。幸好Asp。Net MVC3带来了一个美好的东西,全局Filter。而怎么注册全局Filter呢?答案就在Global.asax中。让我们看以下代码,我是如何将上面我们定义的TestFilterAttribute 注册到全局Filter中。上代码:

     public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
            //注册全局过滤器
            filters.Add(new TestFilterAttribute() { Message="全局"});
        }

效果如下图:

我们看到的结果是全局的Action首先执行,然后才是Controller下的Filter执行,最后才是Action上的标签执行。当然这是在TestFilterAttribute类的定义上打上标记[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]的前提下。不然 如果Action打上了标签跟Controller的相同则它只会执行Action上的Filter。

下面我们说几个系统的Filter

三、AcceptVerbs

规定页面的访问形式,如

        [AcceptVerbs(HttpVerbs.Post)]         public ActionResult Example(){             return View();         }

页面只能以Post形式访问,即表单提交。

四、ActionName

规定Action的名称。

应用场景:如果不想用方法名做为Action名,或Action名为关键字的话,如

       [ActionName("class")]         public ActionResult Example(){             return View();         }

五、NonAction

当前方法仅是普通方法不解析为Action

六、OutputCache

为Action添加缓存

        [OutputCache(Duration = 60, VaryByParam = "*")]        public ActionResult Example()        {            return View();        }

七、ValidateInput

该Action可以接受Html等危险代码(ASP.NET MVC在aspx中设置<%@ Page 的属性无法完成等同任务。)

        [ValidateInput(false)]        public ActionResult Example()        {            return View();        }

八、ValidateAntiForgeryTokenAttribute

用于验证服务器篡改。

        [ValidateAntiForgeryToken]        public ActionResult Example()        {            return View();        }

总结

经过这一篇文章的介绍我们大体了解了Filter的使用方法,还了解到全局Filter的用法,尤其是当相同的Filter重复作用到同一个Action上时,如果没有设置可多次执行的标签那只有Action上的Filter执行,而Controller和全局Filter都被屏蔽掉,但是设置可多次执行,那首先执行全局Filter其次是Controller再次之就是Action上的Filter了。同时还了解了系统的Filter的用法。

作者:boruipower

出处:http://www.cnblogs.com/boruipower

QQ:  1318854011

网店:http://gz168168.taobao.com

【转】Asp.Net MVC3 简单入门详解过滤器Filter,布布扣,bubuko.com

时间: 2024-08-02 07:01:32

【转】Asp.Net MVC3 简单入门详解过滤器Filter的相关文章

Asp.Net MVC3 简单入门详解过滤器Filter

因为是转载文章 在此标明出处,以前有文章是转的没标明的请谅解,因为有些已经无法找到出处,或者与其它原因. 如有冒犯请联系本人,或删除,或标明出处. 因为好的文章,以前只想收藏,但连接有时候会失效,所以现在碰到好的直接转到自己这里. 原文 出处http://www.cnblogs.com/boruipower/archive/2012/11/18/2775924.html 前言 在开发大项目的时候总会有相关的AOP面向切面编程的组件,而MVC(特指:Asp.Net MVC,以下皆同)项目中不想让M

经典ASP.NET MVC3.0入门详解

http://blog.csdn.net/csh624366188/article/details/7064269 :由于本文原在word文档里编写,写本文章时运用了大量截图,直接复制到博客里,没有显示图片, 图片只是一些简单的运行结果截图,不影响大家学习 p.Net MVC已经到第三版了,相信大家也都熟悉了,我也不再重复相关概念性的东西了.但是大家一定要了解,Asp.Net MVC是微软的一 个开源的UI层框架,是AspNet的另外一种开发模式.好废话不多说,那我们开始进入Asp.Net MV

Asp.Net MVC3 简单入门第一季(三)详解Controller之Filter

前言 前面两篇写的比较简单,刚开始写这个系列的时候我面向的对象是刚开始接触Asp.Net MVC的朋友,所以写的尽量简单.所以写的没多少技术含量.把这些技术总结出来,然后一简单的方式让更多的人很好的接受这是我一直努力的方向.后面会有稍微复杂点的项目!让我们一起期待吧! 此文我将跟大家介绍一下Asp.Net MVC3 Filter的一些用法.你会了解和学习到全局Fileter,Action Filter等常用用法. 第一节:Filter知识储备 项目大一点总会有相关的AOP面向切面的组件,而MVC

[MVC.NET] Asp.Net MVC3 简单入门第一季

转自:http://www.cnblogs.com/fly_dragon/archive/2011/10/12/2208042.html 初识Asp.Net MVC2.0 初识Asp.Net MVC2.0[续] Asp.Net MVC2.0 Url 路由入门---实例篇 Asp.Net MVC2.0 Url 路由入门 Asp.Net MVC3 简单入门第一季(一)环境准备 Asp.Net MVC3 简单入门第一季(二)详解Asp.Net MVC3项目 Asp.Net MVC3 简单入门第一季(三

Asp.Net MVC3 简单入门第一季(一)环境准备

前言 大家好,从今天开始我将写一个关于AspNet MVC3方 面学习的总结,并跟初学者一起分享一些基本的基础知识,作者本身也很愿意跟大家一起交流技术,一起交流一起进步,欢迎高手不吝赐教,欢迎大家不同的意见和 建议,作者的学识和见识当然有自己的局限性,希望自己能成为不闷骚型的技术人员,而不是只自己享受技术,而不让更多的人来分享你的成果的人. 第一节:关于Asp.Net MVC3 Asp.Net MVC已经到第三版了,相信大家也都熟悉了,我也不再重复相关概念性的东西了.但是大家一定要了解,Asp.

SQL注入攻防入门详解(2)

SQL注入攻防入门详解 =============安全性篇目录============== 毕业开始从事winfrm到今年转到 web ,在码农届已经足足混了快接近3年了,但是对安全方面的知识依旧薄弱,事实上是没机会接触相关开发……必须的各种借口.这几天把sql注入的相关知识整理了下,希望大家多多提意见. (对于sql注入的攻防,我只用过简单拼接字符串的注入及参数化查询,可以说没什么好经验,为避免后知后觉的犯下大错,专门查看大量前辈们的心得,这方面的资料颇多,将其精简出自己觉得重要的,就成了该文

[转]SQL注入攻防入门详解

原文地址:http://www.cnblogs.com/heyuquan/archive/2012/10/31/2748577.html =============安全性篇目录============== 毕业开始从事winfrm到今年转到 web ,在码农届已经足足混了快接近3年了,但是对安全方面的知识依旧薄弱,事实上是没机会接触相关开发……必须的各种借口.这几天把sql注入的相关知识整理了下,希望大家多多提意见. (对于sql注入的攻防,我只用过简单拼接字符串的注入及参数化查询,可以说没什么

SQL注入攻防入门详解

原文地址:http://www.cnblogs.com/heyuquan/archive/2012/10/31/2748577.html =============安全性篇目录============== 毕业开始从事winfrm到今年转到 web ,在码农届已经足足混了快接近3年了,但是对安全方面的知识依旧薄弱,事实上是没机会接触相关开发……必须的各种借口.这几天把sql注入的相关知识整理了下,希望大家多多提意见. (对于sql注入的攻防,我只用过简单拼接字符串的注入及参数化查询,可以说没什么

【转载】SQL注入攻防入门详解

滴答…滴答…的雨,欢迎大家光临我的博客. 学习是快乐的,教育是枯燥的. 博客园  首页  博问  闪存    联系  订阅 管理 随笔-58 评论-2028 文章-5  trackbacks-0 站长统计|  今日IP[353] | 今日PV[848] | 昨日IP[922] |  昨日PV[2188] |当前在线[10] SQL注入攻防入门详解 =============安全性篇目录============== 毕业开始从事winfrm到今年转到 web ,在码农届已经足足混了快接近3年了,但