zoukankan      html  css  js  c++  java
  • MVC过滤器-->ActionFilterAttribute和HandleErrorAttribute

    自定义的action过滤器  需要继承自ActionFilterAttribute 接口

    OnActionExecuting:  在方法执行之前执行    

    OnActionExecuted:  方法的逻辑代码执行完成之后触发

    OnResultExecuting: 方法在准备放回结果的时候触发

    OnResultExecuted:方法返回结果之后触发

        /// <summary>
        /// 自定义的action过滤器 和result过滤器
        /// </summary>
        public class ActionFilterDemo : ActionFilterAttribute
        {
            /// <summary>
            /// 在方法执行之前被触发
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                //判断如果在控制器上贴有SkipAttribute特性标签则跳过下面代码的执行
                if (filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(SkipAttribute), false))
                {
                    return;
                }
              
                filterContext.HttpContext.Response.Write("1 、OnActionExecuting----<br />");
    
    
                //1.0 获取触发当前方法的action名称
                var actionName = filterContext.ActionDescriptor.ActionName;
    
    
                //2.0 获取action方法所在的控制器
                var cName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
                filterContext.HttpContext.Response.Write("      1.1 、控制器+action=" + cName + actionName + "<br />");
    
    
                //3.0 获取action的参数
                string res = "无参数";
                var prmas = filterContext.ActionParameters;
                if (prmas != null && prmas.Any())
                {
                    res = "";
                    //打印参数名称和值
                    foreach (var ps in prmas)
                    {
                        res += "参数名称=" + ps.Key + ",参数值=" + ps.Value + " | ";
                    }
                }
                filterContext.HttpContext.Response.Write("      1.2 、参数结果:" + res + "<br />");
    
    
    
    
                //4.0 获取当前action上的指定的特性标签HttpGet
                object[] atts = filterContext.ActionDescriptor.GetCustomAttributes(typeof(HttpGetAttribute), false);
                var allAtts = filterContext.ActionDescriptor.GetCustomAttributes(false);//获取所有的特性标签
    
    
    
    
                //4.0.1 判断当前action方法上是否贴有HttpGet的特性标签
                bool isok = filterContext.ActionDescriptor.IsDefined(typeof(HttpGetAttribute), false);
    
    
    
                //5.0 获取当前aciton所在的控制器上的特性标签和判断特性标签
                var allcatts = filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(false);
                var isOK1 = filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(HttpGetAttribute), false);
    
                //6.0 其实OnActionExecuting是在方法执行之前执行的  那么当然也可以用来改造验证同意登陆啦  下面是我自己的尝试
    
                 //获取当前登录url   登陆完毕需要跳转回来的
                  bool  isLogin=false;   //根据项目的登陆方式判断是否登陆
                  if (!isLogin)
                  {
                      string call_back = System.Web.HttpContext.Current.Request.Url.ToString();
                      ContentResult result = new ContentResult();
                      result.Content = "<script>alert('请先登录');window.location.href='http://www.xxoo.com/Passport/Login?callback_url=" + call_back + "'</script>";
                      filterContext.Result = result;
                      return;
                  }
                base.OnActionExecuting(filterContext);
            }
    
            /// <summary>
            /// 方法逻辑代码执行以后被触发
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnActionExecuted(ActionExecutedContext filterContext)
            {
                filterContext.HttpContext.Response.Write("3 、OnActionExecuted----<br />");
                base.OnActionExecuted(filterContext);
            }
    
            /// <summary>
            /// 方法准备返回结果的时候被触发
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnResultExecuting(ResultExecutingContext filterContext)
            {
                filterContext.HttpContext.Response.Write("4 、OnResultExecuting----<br />");
                base.OnResultExecuting(filterContext);
            }
    
            /// <summary>
            /// 方法返回结果后被触发
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnResultExecuted(ResultExecutedContext filterContext)
            {
                filterContext.HttpContext.Response.Write("6 、OnResultExecuted----<br />");
                base.OnResultExecuted(filterContext);
            }
        }

    自定义异常过滤器 继承自HandleErrorAttribute接口

    OnException: 该接口 用户不扣action中没有被try{} catch包括的异常

    /// <summary>
        /// 作用:用于捕获action中的未被try{}catch{}捕获的异常
        /// </summary>
        public class ExpAttribute : HandleErrorAttribute
        {
            public override void OnException(ExceptionContext filterContext)
            {
                
                //1.0获取异常信息
                Exception exp = filterContext.Exception;
    
                //2.0 将信息写入日志或者db中方便查询
               // System.IO.File.AppendAllText(filterContext.HttpContext.Server.MapPath("/Log/log.txt"), exp.ToString());
    
                //3.0 通知MVC框架,现在这个异常已经被我处理掉,你不需要将黄页显示给用户
                filterContext.ExceptionHandled = false;
    
                //4.0 跳转到错误提醒页面
                //filterContext.Result
                filterContext.HttpContext.Response.Redirect("/Error/Error", true);
    
                base.OnException(filterContext);
            }
        }

    其实自定义错误页面还可以换个姿势

    在Web.config中配置

    <customErrors mode="Off" defaultRedirect="Error">       这里的Error页面是views/shared/Error.cshtml页面    
    <!--<error statusCode="404" redirect="/Error/404" />-->  statusCode  定义的 是错误类型      这里的redirect    是自定义的错误页面
    </customErrors>

    ------------------------------最后将过滤器注入到Global.asax文件中

    public class FilterConfig
        {
            public static void RegisterGlobalFilters(GlobalFilterCollection filters)
            {
                filters.Add(new HandleErrorAttribute());
    
                //将ActionFilterDemo 注册成为一个全局过滤器,实现当前网站中的任何action方法被执行的时候都
                //会触发过滤器中的相关方法
                filters.Add(new ActionFilterDemo());
                filters.Add(new AuthAttribute());
    
                filters.Add(new ExpAttribute());
            }
        }
     public class MvcApplication : System.Web.HttpApplication
        {
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
    
                WebApiConfig.Register(GlobalConfiguration.Configuration);
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);  //自定义的过滤器
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);
            }
        }
  • 相关阅读:
    手把手教你学Git
    服务器上Mysql的安装与配置
    python 5
    python 4
    python 3
    python 2
    区分命令行模式和Python交互模式
    CUDA编程模型之内存管理
    多目标优化算法-NSGA2
    C# ListView 如何添加列标头
  • 原文地址:https://www.cnblogs.com/soaeon/p/5635144.html
Copyright © 2011-2022 走看看