MVC有哪几种过滤器?
首先:MVC里面的Filter是切面思想(AOP) ,在不改变方法体的情况下去做一个公有的操作。这样可以对代码做到最大的解耦跟代码复用,实现代码的高可用性。
最近面试好像经常问到这个问题。其实我对概念性的东西不是很感冒,我也许经常用到,但是就是脑子里没有对概念进行过总结归纳,这就是本身有实力但是又不总归纳知识点的人在面试过程中最吃亏最遗憾的地方。下面摘自百度搜索出来的信息。
MVC过滤器分为四种:Authorization(授权),Action(行为),Result(结果)和Exception(异常)
例如很多人需要做签名校验:那么会用Action过滤器
1:首先自定义一个 过滤器,取名:ActionFilter。需要继承:ActionFilterAttribute 这个类 ,ActionFilterAttribute 这个内置的类继承了很多其他接口,
例如:IActionFilter Attribute IFilterMetadata, IAsyncActionFilter, IResultFilter, IAsyncResultFilter, IOrderedFilter等
我们不用管这些,只需要关心 ActionFilterAttribute 需要实现的函数,里面有4个函数,分别是:
OnActionExecuting(ActionExecutedContext context)OnActionExecuted(ActionExecutedContext context) OnResultExecuting(ResultExecutedContext context) OnResultExecuted(ResultExecutedContext context)
注意上面跟下面的2个方法不是一样的,是2个重载方法,参数类型不一致。
上面2个方法代码:后缀是 ing 代码 进去Action之前执行, 后缀 为en 的代表方法结束后执行。
下面2个方法代码:后缀是 ing 代码 进去返回视图之前执行, 后缀 为en 的代表返回视图结束后执行。也就是在控制器里面返回制图 return View(); 这句话的前后。
2:异常过滤器:继承接口:IExceptionFilter
例如:我们需要处理应用程序里面的所有异常就继承IExceptionFilter这个类:例如:
public class ExceptionFilter : IExceptionFilter
{
///
/// 执行
///
///
public void OnException(ExceptionContext filterContext)
{// 处理日志: 获取控制器名称 跟方法
string controllerName = filterContext.RouteData.Values["controller"].ToString();
string actionName = filterContext.RouteData.Values["action"].ToString(); string exception = String.Format("Exception:[{0}] {1}", DateTime.UtcNow.AddHours(8).ToString("yyyyMMdd-HHmmss-fff"), filterContext.Exception.Message);
AppLog.Write(string.Format("异常【{0}/{1}】:{2}", controllerName, actionName, filterContext.Exception), LogMessageType.Error, filterContext.Exception);
filterContext.ExceptionHandled = true; // 代表该异常已处理。其他地方就不需要在处理了。
filterContext.Result = new JsonResult(new BaseResponse { Code = ResCode.System_Error, Message = ResMsg.System_Error }); // 断路器,用来重新制定路由 或者返回信息。结束后面的操作}
}
注意:filter异常可以捕捉到哪些情况:
3:授权fileter 接口重写: 继承类:AuthorizationFilterAttribute
这里写起来就比较复杂,可以理解下思路:
1:肯定要有一个地方存放 用户信息,这里我存放在 Seesion里面去,然后有一个登入的Action及View,在View上有2个控件,账号,密码。登入后把数据可以保存到Seesion这个里面:
HttpContext.Current.Session["LoginUser"] = userDTO;//userDTO登陆用户实体类
2、创建AccountManagerment类下GetCurrentUser()方法,获取Session中存储的用户信息,返回实体类UserDTO
3:创建AccountAuthorizeAttribute类,继承AuthorizeAttribute,并重写OnAuthorization方法
4、将属性[AccountAuthorize]置于整个Controller之上。当用户有操作时,进入控制器前都会先验证用户是否登录,或者存储用户信息过期从而返回登录界面。
注意:这里我们加过滤器Fileter之后,这个fileter可以放在Action上面。代码作用域在这个Action有效。
也可以放在Controller上面。代码对这个Controller有效。那么如何全局有效呢?
那就需要在Global这个全局类里面找到 全局的filter。 看上图,就有一个这个添加全局的filter的方法。然后点击到这个类:
RegisterGlobalFilters中:如图:
需要在RegisterGlobalFilters构造函数方法里面去new一个自定义的filter,就可以对全局有作用了,那样对在controller里面的所有Action都有效。
例如: filters.Add(new ExceptionFilter()); 这个添加到方法里面去就ok了。