这里用实例说明各种过滤器的用法,有不对的地方还请大神指出,共同探讨。

1. actionfilter 方法过滤器:

  接口名为 iactionfilter ,在控制器方法调用前/后执行。

在新建的mvc程序中,添加一个类 myfilter1attribute 并继承actionfilterattribute抽象类

从上图可以看到 actionfilterattribute 中的所有方法,且有相应的介绍,我们可以通过继承 actionfilterattribute 类,并重写(override)它的方法,从而实现自定义filter

   public class myfilter1attribute: actionfilterattribute
    {
        /// <summary>
        /// 该方法会在action方法执行之前调用
        /// </summary>
        /// <param name="filtercontext"></param>
        public override void onactionexecuting(actionexecutingcontext filtercontext)
        {
            filtercontext.httpcontext.response.write("我是onactionexecuting,我在ation方法调用前执行<br/>");
            base.onactionexecuting(filtercontext);
        }


        /// <summary>
        /// 该方法会在action方法执行之后调用
        /// </summary>
        /// <param name="filtercontext"></param>
        public override void onactionexecuted(actionexecutedcontext filtercontext)
        {
            filtercontext.httpcontext.response.write("我是onactionexecuted,我在action方法调用后执行<br/>");
            base.onactionexecuted(filtercontext);
        }

    }

然后创建一个homecontroller控制器,并添加filtertest的测试action

    public class homecontroller : controller
    {
        public actionresult index()
        {
            return view();
        }

        [myfilter1]
        public void filtertest()
        {
            response.write("我是action方法,我在这里执行了.....<br/>");
        }
    }

运行程序并访问filtertest方法:

 上图可看出它的一个执行顺序

 但是有时候也有可能有这样的场景:当检查到action有标识某个attribute的时候,我们需要跳出,并不执行后续的方法的情况,我们可以通过filtercontextactiondescriptior类中的isdefained方法进行判断检查

 

     /// <summary>
        /// 该方法会在action方法执行之前调用
        /// </summary>
        /// <param name="filtercontext"></param>
        public override void onactionexecuting(actionexecutingcontext filtercontext)
        {
            filtercontext.httpcontext.response.write("我是onactionexecuting,我在ation方法调用前执行<br/>");
            //判断action方法时是否有贴上myfilter1attribute标签
            if (filtercontext.actiondescriptor.isdefined(typeof(myfilter1attribute), false))
            {
                //如果有,为该action方法直接返回contentresult,则该action方法在这里就有了返回值,相当于在这里就结束了,不会再去执行之后的方法,例如:onactionexecuted
                filtercontext.result = new contentresult();
            }
            base.onactionexecuting(filtercontext);
        }

 

2.resultfilter 结果过滤器:

  接口名为 iresultfilter,在控制器方法调用完,跳转至view页面前/后调用

 同样在 myfilter1attribute 类中重写 onresultexecuting 方法和  onresultexecuted 方法

        /// <summary>
        /// 该方法在action方法返回结果之前执行
        /// </summary>
        /// <param name="filtercontext"></param>
        public override void onresultexecuting(resultexecutingcontext filtercontext)
        {
            filtercontext.httpcontext.response.write("我是onresultexecuting,我在action方法返回结果前执行<br/>");
            base.onresultexecuting(filtercontext);
        }

        /// <summary>
        /// 该方法在action方法返回结果之后执行
        /// </summary>
        /// <param name="filtercontext"></param>
        public override void onresultexecuted(resultexecutedcontext filtercontext)
        {
            filtercontext.httpcontext.response.write("我是onresultexecuted,我在action方法返回结果后执行<br/>");
            base.onresultexecuted(filtercontext);
        }

然后在homecontroller控制器中添加 filtertest1

        [myfilter1]
        public actionresult filtertest1()
        {
            response.write("我是测试action1方法,我在这里执行了.....<br/>");
            return view();
        } 

运行程序,并访问 filtertest1 ,执行结果如下:

可以看出onresultexecuting 方法是在返回结果页面之前执行的,而onresultexecuted是返回结果页面之后执行的

 

3.exceptionfilter 异常操作过滤器:

  接口名为 iexceptionfilter,在控制器的action方法抛出异常时执行

 可以通过异常过滤器捕获controller中发生的异常,并记录到日志。

添加myexceptionattribute类,并继承handleerrorattribute,如下

        /// <summary>
        /// 
        /// </summary>
        /// <param name="filtercontext"></param>
        public override void onexception(exceptioncontext filtercontext)
        {
            filtercontext.httpcontext.response.write("我是onexception,在controller中发生异常时进入<br/>");

            //获取到异常对象
            exception ex = filtercontext.exception;
            //获取请求的controller和action
            string controllername = filtercontext.routedata.values["controller"].tostring();
            string actionname = filtercontext.routedata.values["action"].tostring();
            //记录日志
            string errmessage = string.format("异常消息:控制器为:{0},action为:{1},异常信息为:{2};", controllername, actionname, ex.message);
            outputlog(errmessage);

            //标记异常已做处理
            filtercontext.exceptionhandled = true;
            base.onexception(filtercontext);
        }

        /// <summary>
        /// 输出日志
        /// </summary>
        /// <param name="message"></param>
        public void outputlog(string message)
        {
            string path = appdomain.currentdomain.basedirectory + "/logs.txt";
            using (streamwriter sw = new streamwriter(path, true, encoding.default))
            {
                sw.flush();
                sw.writeline("时间:" + datetime.now);
                sw.writeline("内容:" + message);
                sw.writeline("---------------------------------------------");
            }
        }

homecontroller中添加filtertest3

 [myexception]
 public actionresult filtertest3()
 {
     response.write("我是测试action3方法,我在这里执行了.....<br/>");
     string str = "131464ddddd";
     int i = int.parse(str);
     return view();
 }

运行程序并访问 filtertest3方法,将会在 str 转换成int类型时抛出异常,随后将进入onexception方法,并记录日志如下:

4.authorizationfilter 授权过滤器:

  接口名为 iauthorizationfilter,在所有过滤器中最先执行

添加一个myfilter2attribute类,并继承authorizeattribute类,然后重写其onauthorization方法:

    public class myfilter2attribute: authorizeattribute
    {

        /// <summary>
        /// 在所有的action方法过滤之前执行
        /// </summary>
        /// <param name="filtercontext"></param>
        public override void onauthorization(authorizationcontext filtercontext)
        {
            filtercontext.httpcontext.response.write("我是onauthorization,在所有action方法过滤器之前执行<br/>");//base.onauthorization(filtercontext);
        }
    }

honecontroller控制器中添加 filtertest2

    [myfilter1]
    [myfilter2]
    public actionresult filtertest2()
    {
        response.write("我是测试action2方法,我在这里执行了.....<br/>");
        return view();
    }

运行程序并访问 filtertest2  结果如下:

从上图执行结果可以看出,onauthorization 权重是最高的,将会在其他所有过滤器之前执行。

 

 

 

注意:

  actionfilter 和 resultfilter 不仅可以对单个方法进行操作,也能对整个controller进行操作,将过滤的头部属性移至控制名称上面即可。