ASP.NET MVC过滤器(一)
2016-07-14 20:39
651 查看
MVC过滤器是加在 Controller 或 Action 上的一种 Attribute,通过过滤器,MVC 网站在处理用户请求时,可以处理一些附加的操作,如:用户权限验证、系统日志、异常处理、缓存等。MVC 中包含Authorization filter、Action filter、Result filter、Exception filter 四种过滤器。
APS.NET MVC中的每一个请求,都会分配给相应的控制器和对应的行为方法去处理,而在这些处理的前前后后如果想再加一些额外的逻辑处理。这时候就用到了过滤器。
Action(行为)
Result(结果)
Exception(异常)
但是默认实现它们的过滤器只有三种,分别是Authorize(授权),ActionFilter,HandleError(错误处理);各种信息如下表所示
2、通过重写Controller方法来使用Filter
定义一个类,继承与AuthorizeAttribute,并重写OnAuthorization方法
这里判断如果,用户没有登录,那么需要返回到登录界面。
虽然定义了一个过滤器,但是还需使用过滤器
使用过滤器的方式也有几种方式:
1、在方法前加上授权特性
这种方式,只能对有加上该授权特性的方法进行登录检查,其它没有加的方法无法进行过滤。在上面代码中,只能对该controller中index的action进行过滤,另外的About和Contact无法过滤。
2、在类上加特性,那么表示对该类下所有方法加上该特性
这种方式虽然不用对每个方法都添加特性,但是也只是对在类上加上了该特性的Controller有作用,其它没有加的会无效
3、注册全局过滤器
在实际项目中,一个项目往往会有很多的Controller和Action那么,如果向上面的两种方式来出来都不够理性,通常我们使用全局过滤器。使用方式
这样就不用再每个类上添加Login过滤器了,默认对每个Controller的每个Action都使用该特性。但是有个问题,就是连登陆页面也被过滤掉了。在这里使用AllowAnonymous都无效
可以在自定义Filter时,通过获取当前访问路径,判断是否是需要排除的路径,如果是,则跳过
这里,以/Account/开始的请求都不会执行该授权过滤器。
方法二:使用重写Controller方法的方式
这种方式相当于在类上使用授权特性,对于该Controller下的所有方法都有效
这里base.OnException(filterContext)不能省略,否则无法捕获到异常
同时在web.config文件中需要配置,启用自定义异常。 <customErrors mode="On"></customErrors>
这两种过滤器都是继承于ActionFilterAttribute类
行为过滤器:需要选择重写OnActionExecuting或者OnActionExecuted,至于是哪个方法看需求,也可以哪个方法都重写
结果过滤器:需要选择重写OnResultExecuting或者OnResultExecuted,至于是哪个方法看需求,也可以哪个方法都重写
APS.NET MVC中的每一个请求,都会分配给相应的控制器和对应的行为方法去处理,而在这些处理的前前后后如果想再加一些额外的逻辑处理。这时候就用到了过滤器。
一、MVC支持的过滤器类型有四种:
Authorization(授权)Action(行为)
Result(结果)
Exception(异常)
滤器类型 | 接口 | 描述 |
Authorization | IAuthorizationFilter | 此类型(或过滤器)用于限制进入控制器或控制器的某个行为方法 |
Exception | IExceptionFilter | 用于指定一个行为,这个被指定的行为处理某个行为方法或某个控制器里面抛出的异常 |
Action | IActionFilter | 用于进入行为之前或之后的处理 |
Result | IResultFilter | 用于返回结果的之前或之后的处理 |
二、使用Filter的方式
1、通过特性的方式使用Filter2、通过重写Controller方法来使用Filter
三、Authorize过滤器
方法一:使用特性的方式定义一个类,继承与AuthorizeAttribute,并重写OnAuthorization方法
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MvcApplication2.Filters { public class LoginAttribute:AuthorizeAttribute { public override void OnAuthorization(AuthorizationContext filterContext) { //如果Session中不存在该值,那么表示没有登录 if (filterContext.HttpContext.Session["User"] == null) { filterContext.Result = new RedirectResult("/Account/Login"); } } } }
这里判断如果,用户没有登录,那么需要返回到登录界面。
虽然定义了一个过滤器,但是还需使用过滤器
使用过滤器的方式也有几种方式:
1、在方法前加上授权特性
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using MvcApplication2.Filters; namespace MvcApplication2.Controllers { public class HomeController : Controller { //在方法上加入授权特性 [Login] public ActionResult Index() { ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application."; return View(); } public ActionResult About() { ViewBag.Message = "Your app description page."; return View(); } public ActionResult Contact() { ViewBag.Message = "Your contact page."; return View(); } } }
这种方式,只能对有加上该授权特性的方法进行登录检查,其它没有加的方法无法进行过滤。在上面代码中,只能对该controller中index的action进行过滤,另外的About和Contact无法过滤。
2、在类上加特性,那么表示对该类下所有方法加上该特性
using System.Web; using System.Web.Mvc; using MvcApplication2.Filters; namespace MvcApplication2.Controllers { [Login] public class HomeController : Controller { public ActionResult Index() { ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application."; return View(); } public ActionResult About() { ViewBag.Message = "Your app description page."; return View(); } public ActionResult Contact() { ViewBag.Message = "Your contact page."; return View(); } } }
这种方式虽然不用对每个方法都添加特性,但是也只是对在类上加上了该特性的Controller有作用,其它没有加的会无效
3、注册全局过滤器
在实际项目中,一个项目往往会有很多的Controller和Action那么,如果向上面的两种方式来出来都不够理性,通常我们使用全局过滤器。使用方式
using System.Web; using System.Web.Mvc; namespace MvcApplication2 { public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { //在此处添加需要注册的全局过滤器 filters.Add(new MvcApplication2.Filters.LoginAttribute()); } } }
这样就不用再每个类上添加Login过滤器了,默认对每个Controller的每个Action都使用该特性。但是有个问题,就是连登陆页面也被过滤掉了。在这里使用AllowAnonymous都无效
可以在自定义Filter时,通过获取当前访问路径,判断是否是需要排除的路径,如果是,则跳过
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MvcApplication2.Filters { public class LoginAttribute:AuthorizeAttribute { public override void OnAuthorization(AuthorizationContext filterContext) { //获取当前相对项目的更目录的路径 string path = filterContext.HttpContext.Request.CurrentExecutionFilePath; if(!path.StartsWith("/Account/", StringComparison.CurrentCultureIgnoreCase)) { //如果Session中不存在该值,那么表示没有登录 if (filterContext.HttpContext.Session["User"] == null) { filterContext.Result = new RedirectResult("/Account/Login"); } } } } }
这里,以/Account/开始的请求都不会执行该授权过滤器。
方法二:使用重写Controller方法的方式
protected override void OnAuthorization(AuthorizationContext filterContext) { //自定义授权验证代码 }
这种方式相当于在类上使用授权特性,对于该Controller下的所有方法都有效
四、异常过滤器
需要继承与HandleErrorAttribute,并重写OnException方法using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MvcApplication2.Filters { public class MyExceptionAttribute:HandleErrorAttribute { public override void OnException(ExceptionContext filterContext) { base.OnException(filterContext); //填写验证信息,记录错误日志 //跳转到错误页面 filterContext.Result = new RedirectResult("/Error"); } } }
这里base.OnException(filterContext)不能省略,否则无法捕获到异常
同时在web.config文件中需要配置,启用自定义异常。 <customErrors mode="On"></customErrors>
五、行为和结果过滤器
这两种过滤器都是继承于ActionFilterAttribute类行为过滤器:需要选择重写OnActionExecuting或者OnActionExecuted,至于是哪个方法看需求,也可以哪个方法都重写
结果过滤器:需要选择重写OnResultExecuting或者OnResultExecuted,至于是哪个方法看需求,也可以哪个方法都重写
相关文章推荐
- 用ASP实现文件下载
- asp.net mvc ajax分页 CPager(秒杀杨涛ajax分页) 封装之前
- ASP.Net Core-TagHelpers
- ASP.NET Core Token认证
- asp.net mvc 之旅 —— 第六站 ActionFilter的应用及源码分析
- ASP.NET Web API 自定义MediaType实现jsonp跨域调用
- Asp.Net Unix时间戳和DateTime类型转换
- 转:ASP.NET 使用Ajax
- ASP.NET MD5加密
- 收藏:ASP.NET提供文件下载函数(支持大文件、续传、速度限制、资源占用小) (转自: Arhrun)
- 各版本IIS下ASP.net请求处理过程区别
- ASP.net:截取固定长度字符串显示在页面,多余部分显示为省略号
- ASP.NET发送电子邮件
- asp.net SessionState之sqlserver模式
- asp.net 如何引用dll
- [译]初识.NET Core & ASP.NET Core
- 【Asp.Net Core】一、Visual Studio 2015 和 .NET Core 安装
- 为何没有.aspx.designer.cs文件?
- 【转】asp.net(c#)加密解密算法之sha1、md5、des、aes实现源码详解
- ASP.NET Web API系列——选择Web API还是WCF