过滤器(Filter)

    AOP(面向切面编程)是一种架构思想,用于把公共的逻辑放到一个单独的地方,这样就不用每个地方都写重复的代码,比如程序中发生异常,不用每个地方都try catch 只要在(golbal的Application_Error)中统一进行异常处理。不用每个Actuon中都检查当前用户是否有执行权限,Asp.net.mvc中提供一个机制,每个Action执行之前都会执行我们的代码,统一检查即可。

    一夫当关,万夫莫开!

   1、 四种Filter :

          在 ASP.NET MVC中提供了四个Filter(过滤器)接口实现了这种AOP机制,IAuthorizationFilter、IActionFilter、IResultFilter、IExceptionFilter

          (1) IAuthorizationFilter 一般用来检查当前用户是否有Action的执行权限,在每个Action被执行钱执行OnAuthorization 方法;

        (2)IActionFilter 也是在每个Action被执行前执行OnActionExecuting 方法,每个Action执行完成后执行OnActionExecuted 方法。和IAuthorizationFilter的区别是IAuthorizationFilter在IActionFilter之前执行,检查权限一般写到IAuthorizationFilter中;

        (3)IResultFilter ,在每个ActionResult的前后执行IResultFilter,用的很少,后面有一个应用。

         (4) IExceptionFilter,当Action执行发生为处理异常的时候执行OnException方法。在asp.net MVC中仍然可以使用"Global"的“Application_error”,但是建议用IExceptionFilter

             定义的类可以在Global中GlobalFilter.Filters.Add(new ****Filter())的方式添加为全局的过滤器;

  2、 IAuthorizationFilter:

          在Global.asax文件里添加: GlobalFilters.Filters.Add(new CheckLoginFilter());

    public class CheckLoginFilter : IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            string ctrlName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
            string actionName = filterContext.ActionDescriptor.ActionName;
            if(ctrlName=="Login"&&(actionName=="Index"||actionName=="Login"))
            {
                //什么都不做
            }
            else//检查登陆状态
            {
                if(filterContext.HttpContext.Session["username"]==null)
                {
                    ContentResult contentResult = new ContentResult();
                    contentResult.Content = "没有登陆";

                    //如果在Filter中给filterContent.Result赋值了,那么将不再继续执行要执行的Filter
                    //而是把filterContext.Result执行返回给用户,filterContext.Result是阻止Action执行的
                    // filterContext.Result = contentResult;
                    filterContext.Result = new RedirectResult("/Login/Index");//重定向
                }
            }


        }
    }
//Login/Index.csshtml

<form action="~/Login/Login" method="post">
    用户名:<input  type="text" name="username" />
    密码:  <input  type="password" name="password"/>
    <input  type="submit" value="登陆"/>
</form>
    public class LoginController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
        public ActionResult Login(string username ,string password)
        {
            if(username == "admin"&& password=="123")
            {
                Session["username"] = "admin";
                return Content("登陆成功");
            }
            else
            {
                return Content("登陆失败");
            }
        }
    }
    public class MainController : Controller
    {
        // GET: Main
      
        public ActionResult Main()
        {
            return Content("已登陆主页"+Session["username"]);
        }
    }

 3、IActionFilter:

      在Global.asax文件里添加: GlobalFilters.Filters.Add(new LogActionFilter());

    public class LogActionFilter : IActionFilter
    {
        //Action执行后
        public void OnActionExecuted(ActionExecutedContext filterContext)
        {
            string actionName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
            string controllName = filterContext.ActionDescriptor.ActionName;
            string path = filterContext.HttpContext.Server.MapPath("~/log.txt");
            File.AppendAllText(path, "已经执行" + controllName + "." + actionName);

        }
        //Action执行前
        public void OnActionExecuting(ActionExecutingContext filterContext)
        {
            string actionName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
            string controllName = filterContext.ActionDescriptor.ActionName;
            string path = filterContext.HttpContext.Server.MapPath("~/log.txt");
            File.AppendAllText(path, "将要执行" + controllName + "." + actionName);
        }
    }

4、IExceptionFilter

    public class ExceptionFilter : IExceptionFilter
    {
        public void OnException(ExceptionContext filterContext)
        {
            string path = filterContext.HttpContext.Server.MapPath("~/log.txt");
            Exception ex = filterContext.Exception;
            File.AppendAllText(path, ex.ToString()+"\n");
        }
    }

          总结:全局Filter 一次编写,其他地方默认执行,可以添加多个同一个类型的全局Filter,按照添加顺序执行;

5、非全局Filter:只要让类继承自FilterAttribute类,然后该实现那个Filter接口就实现那个,不添加到GlobalFilter里,而是把自定义的Attribute添加到Controller类上或者Action方法上,这样Controller或者Action会执行;

猜你喜欢

转载自www.cnblogs.com/fuyouchen/p/9378791.html