本文,介绍了Filter在MVC请求的生命周期中的做用和角色,以及Filter的一些经常使用应用场景。 同时针对MVC中的对于Session,Cookie等的依赖,如何使用Filter解依赖。session
若是你们有什么好的Filter应用方法,但愿一块儿多交流。mvc
阅读目录:asp.net
1、Filter在MVC生命周期中的位置ide
2、Filter常见的应用场景单元测试
3、Filter的执行顺序测试
4、MVC中常见的对于Session, Cookie的依赖spa
5、使用Filter解除依赖.net
下面的图中, 一个完成的MVC的生命周期分为5个步骤, 对应图例中的1~5日志
Filter在MVC的生命周期中的角色就像是一个一个的截面,在MVC的处理过程当中,拦截请求。code
Filter分为:
Authorization filters – 须要实现IAuthorizationFilter接口,用于验证处理验证相关的操做
Action filters –须要实现IActionFilter接口. 在Action处理的开始和结束作拦截操做
Result filters – 须要实现IResultFilter接口. 在View呈现前和呈现后作处理
Exception filters – 须要实现IExceptionFilter接口,只要是添加了Exception Filter的请求中出现异常,都会被拦截
每一个Filter的做用时机,对应于下图中的2a, 2b, 4a, 4b.
下面是我的在开发中,经常使用到的Filter处理:
权限验证
使用Authorization filters,拦截请求,在进入到Controller处理以前,验证用户是否登陆或者登陆用户是否有权限访问改页面。
若是合法,就继续交由Controller处理,若是非法,中断流程,跳转到登陆页面。
日志记录
经过Action Filter跟踪记录Action处理开始的时间,结束时间,访问的具体Controller和Action, 参数,访问者ip等信息。
异常处理
异常处理Exception filter可以在发生异常的时候,记录异常信息。若是是session过时引发的异常,则跳转到登陆页面,若是是程序运行致使的没法处理异常,则跳转到友好的错误页面。
提高SEO效果
每篇博客文章的meta信息可以帮助提升SEO效果,可是不少人对于填写keyword, description等信息以为太繁琐。
可使用Result filters,在最后呈现页面前,使用程序分析内容,提取keyword和description来,而后填充到meta信息中。
这样,每篇博客文章都可以有程序实现最佳的SEO效果,甚至生成一份SEO报告出来。
Filter之间执行的顺序,首先根据类型区分:
分别是Authorization filters, Action filters, Result filters. Exception Filter没有列入的缘由是, 它是在发生异常的时候处理,没有特定的顺序。
当同时一个类型的Filter的时候,执行顺序能够经过Filter的Order属性来排序。
在Web程序中,对于Session和Cookie等的使用是必不可少的。
好比, 不少的Action的代码中,会要从Session中获取当前登陆用户信息:
public ActionResult Index() { var user = Session[“UserAccuont”];//从Session中获取当前登陆用户的信息 //send email var email = user.Email; ………… }
上面的Index方法的问题就是和Session耦合,很难单元测试。
下面介绍如何使用Filter来解除对于Session的依赖。
添加一个SessionUserParameterAttribute的Action Filter, 它的功能是:
从Session中取得User, 将取得的User赋值给Action中的参数sessionUser.
public class SessionUserParameterAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { const string key = "sessionUser"; if (filterContext.ActionParameters.ContainsKey(key)) { filterContext.ActionParameters[key] = Session[“UserAccuont”];//为Action设置参数 } base.OnActionExecuting(filterContext); } }
改造后的Index Action方法以下:
[SessionUserParameter] public ActionResult Index(UserAccount sessionUser) { //send email var email = sessionUser.Email; ………… }
这样Index方法就解除了对于Session的依赖, 而只是依赖于一个普通的实体类UserAccount.
在单元测试中,只须要简单的构造一个UserAccount的对象就能够了。