博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET MVC过滤器(一)
阅读量:7037 次
发布时间:2019-06-28

本文共 5650 字,大约阅读时间需要 18 分钟。

  MVC过滤器是加在 Controller 或 Action 上的一种 Attribute,通过过滤器,MVC 网站在处理用户请求时,可以处理一些附加的操作,如:用户权限验证、系统日志、异常处理、缓存等。MVC 中包含Authorization filter、Action filter、Result filter、Exception filter 四种过滤器。

  APS.NET MVC中的每一个请求,都会分配给相应的控制器和对应的行为方法去处理,而在这些处理的前前后后如果想再加一些额外的逻辑处理。这时候就用到了过滤器。

一、MVC支持的过滤器类型有四种:

  Authorization(授权)

  Action(行为)

  Result(结果)

  Exception(异常)

滤器类型

接口

描述

Authorization

IAuthorizationFilter

此类型(或过滤器)用于限制进入控制器或控制器的某个行为方法

Exception

IExceptionFilter

用于指定一个行为,这个被指定的行为处理某个行为方法或某个控制器里面抛出的异常

Action

IActionFilter

用于进入行为之前或之后的处理

Result

IResultFilter

用于返回结果的之前或之后的处理

 

  但是默认实现它们的过滤器只有三种,分别是Authorize(授权),ActionFilter,HandleError(错误处理);各种信息如下表所示

 

二、使用Filter的方式

  1、通过特性的方式使用Filter

  2、通过重写Controller方法来使用Filter

 

三、Authorize过滤器

方法一:使用特性的方式

  定义一个类,继承与AuthorizeAttribute,并重写OnAuthorization方法

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6  7 namespace MvcApplication2.Filters 8 { 9     public class LoginAttribute:AuthorizeAttribute10     {11         public override void OnAuthorization(AuthorizationContext filterContext)12         {13             //如果Session中不存在该值,那么表示没有登录14             if (filterContext.HttpContext.Session["User"] == null)15             {16                 filterContext.Result = new RedirectResult("/Account/Login");17             }18         }19     }20 }

  这里判断如果,用户没有登录,那么需要返回到登录界面。

  虽然定义了一个过滤器,但是还需使用过滤器

 

使用过滤器的方式也有几种方式:

1、在方法前加上授权特性

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 using MvcApplication2.Filters; 7  8 namespace MvcApplication2.Controllers 9 {10     public class HomeController : Controller11     {12         //在方法上加入授权特性13         [Login]14         public ActionResult Index()15         {16             ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";17 18             return View();19         }20 21         public ActionResult About()22         {23             ViewBag.Message = "Your app description page.";24 25             return View();26         }27 28         public ActionResult Contact()29         {30             ViewBag.Message = "Your contact page.";31 32             return View();33         }34     }35 }

   这种方式,只能对有加上该授权特性的方法进行登录检查,其它没有加的方法无法进行过滤。在上面代码中,只能对该controller中index的action进行过滤,另外的About和Contact无法过滤。

 

2、在类上加特性,那么表示对该类下所有方法加上该特性

1 using System.Web; 2 using System.Web.Mvc; 3 using MvcApplication2.Filters; 4  5 namespace MvcApplication2.Controllers 6 { 7     [Login] 8     public class HomeController : Controller 9     {10         public ActionResult Index()11         {12             ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";13 14             return View();15         }16 17         public ActionResult About()18         {19             ViewBag.Message = "Your app description page.";20 21             return View();22         }23 24         public ActionResult Contact()25         {26             ViewBag.Message = "Your contact page.";27 28             return View();29         }30     }31 }

  这种方式虽然不用对每个方法都添加特性,但是也只是对在类上加上了该特性的Controller有作用,其它没有加的会无效

 

3、注册全局过滤器

  在实际项目中,一个项目往往会有很多的Controller和Action那么,如果向上面的两种方式来出来都不够理性,通常我们使用全局过滤器。使用方式

1 using System.Web; 2 using System.Web.Mvc; 3  4 namespace MvcApplication2 5 { 6     public class FilterConfig 7     { 8         public static void RegisterGlobalFilters(GlobalFilterCollection filters) 9         {10             //在此处添加需要注册的全局过滤器11             filters.Add(new MvcApplication2.Filters.LoginAttribute());12         }13     }14 }

  这样就不用再每个类上添加Login过滤器了,默认对每个Controller的每个Action都使用该特性。但是有个问题,就是连登陆页面也被过滤掉了。在这里使用AllowAnonymous都无效

    可以在自定义Filter时,通过获取当前访问路径,判断是否是需要排除的路径,如果是,则跳过

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6  7 namespace MvcApplication2.Filters 8 { 9     public class LoginAttribute:AuthorizeAttribute10     {11         public override void OnAuthorization(AuthorizationContext filterContext)12         {13             //获取当前相对项目的更目录的路径14             string path = filterContext.HttpContext.Request.CurrentExecutionFilePath;15             if(!path.StartsWith("/Account/", StringComparison.CurrentCultureIgnoreCase))16             {17                 //如果Session中不存在该值,那么表示没有登录18                 if (filterContext.HttpContext.Session["User"] == null)19                 {20                     filterContext.Result = new RedirectResult("/Account/Login");21                 }22             }23             24         }25     }26 }

  这里,以/Account/开始的请求都不会执行该授权过滤器。

 

方法二:使用重写Controller方法的方式

1 protected override void OnAuthorization(AuthorizationContext filterContext)2  {3         //自定义授权验证代码4  }

  这种方式相当于在类上使用授权特性,对于该Controller下的所有方法都有效

 

 

四、异常过滤器

  需要继承与HandleErrorAttribute,并重写OnException方法

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6  7 namespace MvcApplication2.Filters 8 { 9     public class MyExceptionAttribute:HandleErrorAttribute10     {11         public override void OnException(ExceptionContext filterContext)12         {13             base.OnException(filterContext);14             15             //填写验证信息,记录错误日志16 17             //跳转到错误页面18             filterContext.Result = new RedirectResult("/Error");19         }20     }21 }

  这里base.OnException(filterContext)不能省略,否则无法捕获到异常

  同时在web.config文件中需要配置,启用自定义异常。    <customErrors mode="On"></customErrors>

五、行为和结果过滤器

  这两种过滤器都是继承于ActionFilterAttribute类

  行为过滤器:需要选择重写OnActionExecuting或者OnActionExecuted,至于是哪个方法看需求,也可以哪个方法都重写

  结果过滤器:需要选择重写OnResultExecuting或者OnResultExecuted,至于是哪个方法看需求,也可以哪个方法都重写

  

 

转载地址:http://qxnal.baihongyu.com/

你可能感兴趣的文章
几个免费IP地址查询API接口
查看>>
Linux之时间服务器NTP
查看>>
IP首部校验和的计算
查看>>
JS使用getComputedStyle()方法获取CSS属性值
查看>>
nginx自定义header头内容丢失
查看>>
配置路由器/交换机的Telnet登录
查看>>
重装eclipse遇到的一些问题整理
查看>>
短信验证码接收app必须注意的那些事
查看>>
HTTP通俗介绍
查看>>
HttpClient以及Json传递的一些坑
查看>>
loadrunner11压力测试自学成才!嘎嘎
查看>>
Ext.Net系列:二Event之DirectEvent 示例1-调用事件顺序
查看>>
基于搜狗搜索的微信公众号爬虫实现(C#版本)
查看>>
朋友们谁知道哪里培训PHP比较靠谱的?
查看>>
cnetos6上实现nfs共享
查看>>
若是在做销售源码生意的,还是用 VS2008 省事一些,今天有一个客户没 VS2010 只好再把程序倒退回来...
查看>>
.NET大型C/S系统可动态设置登录窗口的实现参考
查看>>
磁盘的读写原理
查看>>
转-快速编辑Shell命令行
查看>>
【中医养生门户网】注意!春分在于“生、升”,保肝促阳为重
查看>>