zoukankan      html  css  js  c++  java
  • mvc 过滤器

    1,在项目中添加Filters文件夹,所有Filters都放置在该文件夹中,方便后期归档

    2,在Filters文件夹中添加一个类:CheckUserRoleAttribute.cs,在这里我们按照MVC约定的方式来命名,过滤器以Attribute来结尾。让其继承: System.Web.Mvc.ActionFilterAttribute。查看ActionFilterAttribute定义,其成员如下:

    复制代码
    // 摘要: 
    //     在执行操作方法后由 ASP.NET MVC 框架调用。
    //
    // 参数: 
    //   filterContext:
    //     筛选器上下文。
    public virtual void OnActionExecuted(ActionExecutedContext filterContext);
    //
    // 摘要: 
    //     在执行操作方法之前由 ASP.NET MVC 框架调用。
    //
    // 参数: 
    //   filterContext:
    //     筛选器上下文。
    public virtual void OnActionExecuting(ActionExecutingContext filterContext);
    //
    // 摘要: 
    //     在执行操作结果后由 ASP.NET MVC 框架调用。
    //
    // 参数: 
    //   filterContext:
    //     筛选器上下文。
    public virtual void OnResultExecuted(ResultExecutedContext filterContext);
    //
    // 摘要: 
    //     在执行操作结果之前由 ASP.NET MVC 框架调用。
    //
    // 参数: 
    //   filterContext:
    //     筛选器上下文。
    public virtual void OnResultExecuting(ResultExecutingContext filterContext);
    复制代码

    看注解可以知道4个成员:

    OnActionExecuted
    OnActionExecuting
    OnResultExecuted
    OnResultExecuted

    而我一般都是重写OnActionExecuting方法:

    复制代码
    public class CheckUserRoleAttribute : System.Web.Mvc.ActionFilterAttribute
    {
        public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext)
        {
            /*
             * 这里为了方便演示,直接在请求参数中获取了userName
             * 假设某一个Action只有Lucy可以访问。
             */
            string userName = filterContext.HttpContext.Request["userName"];
            if (userName=="Lucy")
            {
                base.OnActionExecuting(filterContext);
                return;
            }
            else
            {
                //这里构造了一个心得ActionResult.如果userName不是Lucy,则返回权限不足
                filterContext.Result = new System.Web.Mvc.ContentResult() { Content = "权限不足,无法访问" };
                return;
            }
        }
    }
    复制代码

    然后在HomeController中添加SayHello(),并且添加特性[CheckUserRole]

    复制代码
    public class HomeController : Controller
    {
        [HttpGet]
        public ActionResult Index(string msg)
        {
            return Content("I'm come from Get Method.");
        }
    
        [HttpPost]
        public ActionResult Index()
        {
            return Content("I'm come from Post Method.");
        }
    
        //添加特性
        [Filters.CheckUserRole]
        public ActionResult SayHello()
        {
            return Content("我是Lucy,这只能给我访问");
        }
    }
    复制代码

    点击调试:

    这样子,一个简单的过滤器就实现了。

    我们可以根据实际的逻辑去重写自己的过滤器。

    **********************简单优雅的分隔符**********************

    另外一个比较常用的是异常过滤器

    1,同样新建SystemErrorAttribute.cs

    需要注意,这里继承的是:System.Web.Mvc.HandleErrorAttribute

    复制代码
    public class SystemErrorAttribute : System.Web.Mvc.HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
            base.OnException(filterContext);
            //处理错误消息,将其跳转到一个页面
            string controllerName = (string)filterContext.RouteData.Values["controller"];
            string actionName = (string)filterContext.RouteData.Values["action"];
            //这里简单向C盘的test.log写入了文件
            FileStream fs = new FileStream(@"C:	est.log", FileMode.OpenOrCreate, FileAccess.Write);
            StreamWriter sw = new StreamWriter(fs);
            sw.BaseStream.Seek(0, SeekOrigin.End);
            string writeText = string.Format("controllerName:[{0}]actionName:[{1}]{2}",
                controllerName, actionName, filterContext.Exception.ToString());
            sw.WriteLine(writeText);
            sw.Flush();
            sw.Close();
            fs.Close();
    
            /*//这里是使用log4net来记录
            log4net.ILog log = log4net.LogManager.GetLogger("controllerName:[" + controllerName + "]actionName:[" + actionName+"]");
            log.Error(filterContext.Exception.ToString());
            */
    
            //錯誤友好輸出,这里重新构造了一个ActionResult
            filterContext.Result = new System.Web.Mvc.ContentResult() { Content = "系统错误,请联系管理员" };
            return;
        }
    }
    复制代码

    2,在HomeController中添加MyError()

    复制代码
    public class HomeController : Controller
    {
        [Filters.SystemError]//添加
        public ActionResult MyError()
        {
            //人为制造一个错误
            int a = 1;
            int b = 0;
            return Content((a/b).ToString());
        }
    }
    复制代码

    3,调试:注意:这里需要采用Ctrl+F5的方式运行,结果如下:

    到这里,可能会有很大疑问,为什么没有产生友好提示呢?在过滤器中不是明明有添加友好提示吗?

    先看一下C盘的日志:test.log

    日志有成功产生。没有出现友好提示的原因在于不是正式的环境,VS为了方便调试,不会隐藏错误信息。下面将应用部署到真实的环境中去调试,看结果:

    这下友好提示又出来了。。。

    当然对于异常处理过滤器来说,我在每个Action都来添加特性,还是很麻烦,这里我们就要注册成为全局过滤器:

    ①,打开App_Start文件夹中的FilterConfig.cs

    添加:filters.Add(new Filters.SystemErrorAttribute());

    复制代码
    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            //添加这个
            filters.Add(new Filters.SystemErrorAttribute());
    
            filters.Add(new HandleErrorAttribute());
        }
    }
    复制代码

    ②,在HomeController去掉[Filters.SystemError]特性,然后发布,调试结果:结果一样

    就这样,全局异常处理就完成了。

    2、对于过滤器,我们可以把它们加在三个地方,一个是控制器上面(控制器下面的所有Action),一个是Action上面(指定标识的Action),另一个就是全局位置(所有控制器中的Action)。这里我只演示在Action上面加

    复制代码
           [MyCustormFilter]
            public ActionResult Index()
            {
                return View();
            }
           public ActionResult Index1()
           {
               return View();
    }   
    复制代码

    3、build然后运行

    Result

     1、新建类TestResultFilter,继承ActionFilterAttribute

    复制代码
      public class TestResultFilter:ActionFilterAttribute
        {
            /// <summary>
            /// 加载 "视图" 前执行
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnResultExecuting(System.Web.Mvc.ResultExecutingContext filterContext)
            {
                filterContext.HttpContext.Response.Write("加载视图前执行 OnResultExecuting <br/>");
                base.OnResultExecuting(filterContext);
            }
    
            /// <summary>
            /// 加载"视图" 后执行
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnResultExecuted(System.Web.Mvc.ResultExecutedContext filterContext)
            {
                filterContext.HttpContext.Response.Write("加载视图后执行 OnResultExecuted <br/>");
                base.OnResultExecuted(filterContext);
            }
        }
    复制代码

    2、这里我把TestResultFilter过滤器加在控制器上面

    复制代码
      [TestResultFilter]
        public class FilterTestController : Controller
        {
           [MyCustormFilter]
            public ActionResult Index()
            {
                return View();
            }
           public ActionResult Index1()
           {
               return View();
           }
        }
    复制代码

    3、运行看下结果

    注意:Result过滤器,无论Action的返回类型为什么(甚至void)都将执行。

    RouteData中保存了当前请求匹配的路由信息和路由对象

    修改MyCustormFilter.cs

    复制代码
     public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                //1.获取获取请求的类名和方法名
                string strController = filterContext.RouteData.Values["controller"].ToString();
                string strAction = filterContext.RouteData.Values["action"].ToString();//2.另一种方式 获取请求的类名和方法名
                string strAction2 = filterContext.ActionDescriptor.ActionName;
                string strController2 = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
    
                filterContext.HttpContext.Response.Write("Action执行前</br>");
                filterContext.HttpContext.Response.Write("控制器:" + strController + "</br>");
                filterContext.HttpContext.Response.Write("控制器:" + strController2+"</br>");
                filterContext.HttpContext.Response.Write("Action:" + strAction + "</br>");
                filterContext.HttpContext.Response.Write("Action:" + strAction2 + "</br>");
                base.OnActionExecuting(filterContext);
            }
    复制代码

     

    AuthorizeAttribute

    1、  新建TestAuthorizeAttribute

    复制代码
        /// <summary>
        /// 授权过滤器 --在Action过滤器前执行
        /// </summary>
        public class TestAuthorizeAttribute:AuthorizeAttribute
        {
            public override void OnAuthorization(AuthorizationContext filterContext)
            {
                filterContext.HttpContext.Response.Write("<br/>OnAuthorization<br/>");
                //注释掉父类方法,因为父类里的 OnAuthorization 方法会调用asp.net的授权验证机制!
                //base.OnAuthorization(filterContext);
            }
    }
    复制代码

    2、在控制器FilterTest中的Index上添加TestAuthorize标记

           [MyCustormFilter]
           [TestAuthorize]
            public ActionResult Index()
            {
                return View();
            }

    运行看下结果:

    Exception

    1、新建TestHandleError.cs

    复制代码
        /// <summary>
        /// 异常处理 过滤器
        /// </summary>
        public class TestHandleError : HandleErrorAttribute
        {
            public override void OnException(ExceptionContext filterContext)
            {
                //1.获取异常对象
                Exception ex = filterContext.Exception;
                //2.记录异常日志
                //3.重定向友好页面
                filterContext.Result = new RedirectResult("~/error.html");
                //4.标记异常已经处理完毕
                filterContext.ExceptionHandled = true;
    
                base.OnException(filterContext);
            }
        }
    复制代码

    2、在Action上面加TestHandleError

    复制代码
      [TestHandleError]
           public ActionResult GetErr()
           {
               int a = 0;
               int b = 1 / a;
               return View();
           }
    复制代码

    注意:通常这样的异常处理我们是放在全局过滤器上面的。

    复制代码
       public class FilterConfig
        {
            public static void RegisterGlobalFilters(GlobalFilterCollection filters)
            {
                //filters.Add(new HandleErrorAttribute());
                //添加全局过滤器
                filters.Add(new TestHandleError());
            }
        }
  • 相关阅读:
    服务控制器
    .Net Web项目安装包制作 (一)
    C#制作Windows service服务系列一:制作一个可安装、可启动、可停止、可卸载的Windows
    用Visual C#创建Windows服务程序
    插件的“动态替换”
    .Net Web项目安装包制作(三)补充说明
    .net打包/C#WinFrom程序打包
    C#制作Windows service服务系列三制作可控制界面的Windows服务(windows service)
    C#制作Windows service服务系列二演示一个定期执行的windows服务及调试
    .Net Web项目安装包制作 (二)数据库安装、其他组件的安装
  • 原文地址:https://www.cnblogs.com/yushaohua/p/5408249.html
Copyright © 2011-2022 走看看