• ASP.NET MVC 中的过滤器


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

    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);
            }
    View Code

    然后在HomeController控制器中添加 FilterTest1

            [MyFilter1]
            public ActionResult FilterTest1()
            {
                Response.Write("我是测试Action1方法,我在这里执行了.....<br/>");
                return View();
            } 
    View Code

    运行程序,并访问 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("---------------------------------------------");
                }
            }
    View Code

    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进行操作,将过滤的头部属性移至控制名称上面即可。

  • 相关阅读:
    iOS开发--CoreGraphics简单绘图
    iOS开发--UITableView
    PowerDesigner
    使用jquery-qrcode生成二维码
    MVC中如何设置路由指定默认页
    项目管理
    版本管理
    如何在网页中嵌入百度地图
    asp.net网站中添加百度地图功能
    TCP/UDP简易通信框架源码,支持轻松管理多个TCP服务端(客户端)、UDP客户端
  • 原文地址:https://www.cnblogs.com/Struggle-xh/p/11400368.html
Copyright © 2020-2023  润新知