好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

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

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

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

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

判断登录与否或用户权限 决策输出缓存 防盗链 防蜘蛛 本地化与国际化设置  实现动态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

 

 

 

 

 

 

分类:  MVC

标签:  MVC ,  aspnet ,  Filter ,  Action Filter ,  过滤器 ,  Attribute ,  系统Filter

作者: Leo_wl

    

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

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于Asp.Net MVC3 简单入门详解过滤器Filter的详细内容...

  阅读:48次