欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ASP.NET MVC 中的过滤器

程序员文章站 2022-07-01 16:26:28
这里用实例说明各种过滤器的用法,有不对的地方还请大神指出,共同探讨。 1. ActionFilter 方法过滤器: 接口名为 IActionFilter ,在控制器方法调用前/后执行。 在新建的MVC程序中,添加一个类 MyFilter1Attribute 并继承ActionFilterAttrib ......

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

1. actionfilter 方法过滤器:

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

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

ASP.NET MVC 中的过滤器

从上图可以看到 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方法:

ASP.NET MVC 中的过滤器

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

 但是有时候也有可能有这样的场景:当检查到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 ,执行结果如下:

ASP.NET MVC 中的过滤器

可以看出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方法,并记录日志如下:

ASP.NET MVC 中的过滤器

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  结果如下:

ASP.NET MVC 中的过滤器

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

 

 

 

注意:

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