MVC 几种过滤器及如何使用

MVC有哪几种过滤器?

首先:MVC里面的Filter是切面思想(AOP) ,在不改变方法体的情况下去做一个公有的操作。这样可以对代码做到最大的解耦跟代码复用,实现代码的高可用性。

最近面试好像经常问到这个问题。其实我对概念性的东西不是很感冒,我也许经常用到,但是就是脑子里没有对概念进行过总结归纳,这就是本身有实力但是又不总归纳知识点的人在面试过程中最吃亏最遗憾的地方。下面摘自百度搜索出来的信息。  

MVC过滤器分为四种:Authorization(授权),Action(行为),Result(结果)和Exception(异常)

MVC 几种过滤器及如何使用_第1张图片
 

例如很多人需要做签名校验:那么会用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异常可以捕捉到哪些情况:

  1. action内的异常  可以
  2. action调用的bll  dll  modle里面的方法,可以
  3. 如果上面2中情况下,action本身用到了try cach 那么  不可以再捕捉到异常,因为内部自己处理了异常,就等于已经没有异常
  4. 视图View里面报错 了,  可以
  5. controller的构造函数异常, 不可以 
  6. 没有找到action     不可以
  7. 没有找到conroller 不可以 
  8. 其他的fiter异常。例如AuthorizationFilterAttribute 里面报错,  可以 

这里需要用IL反编译器查看一下 mvc下的fitler操作原理: 封装里面有一个方法,里面用到了try catch 捕捉异常信息。首先,通过访问里的http协议里的ip +port 可以路由到封装的方法里面,首先要 实例化 controller ,然后 再找到action  后面再会  try catch 里面的里面的操作。例如:

   找到action里面的所有 Filter ,调用action  返回cview视图 都在这个异常里面、所以才可以捕捉到这些异常。 

 

3:授权fileter 接口重写: 继承类:AuthorizationFilterAttribute

这里写起来就比较复杂,可以理解下思路:

1:肯定要有一个地方存放 用户信息,这里我存放在 Seesion里面去,然后有一个登入的Action及View,在View上有2个控件,账号,密码。登入后把数据可以保存到Seesion这个里面:

HttpContext.Current.Session["LoginUser"] = userDTO;//userDTO登陆用户实体类

2、创建AccountManagerment类下GetCurrentUser()方法,获取Session中存储的用户信息,返回实体类UserDTO

 MVC 几种过滤器及如何使用_第2张图片

3:创建AccountAuthorizeAttribute类,继承AuthorizeAttribute,并重写OnAuthorization方法

MVC 几种过滤器及如何使用_第3张图片

4、将属性[AccountAuthorize]置于整个Controller之上。当用户有操作时,进入控制器前都会先验证用户是否登录,或者存储用户信息过期从而返回登录界面。

 

注意:这里我们加过滤器Fileter之后,这个fileter可以放在Action上面。代码作用域在这个Action有效。

也可以放在Controller上面。代码对这个Controller有效。那么如何全局有效呢?
 

MVC 几种过滤器及如何使用_第4张图片

那就需要在Global这个全局类里面找到  全局的filter。 看上图,就有一个这个添加全局的filter的方法。然后点击到这个类:

RegisterGlobalFilters中:如图:

需要在RegisterGlobalFilters构造函数方法里面去new一个自定义的filter,就可以对全局有作用了,那样对在controller里面的所有Action都有效。

例如:        filters.Add(new ExceptionFilter());  这个添加到方法里面去就ok了。

MVC 几种过滤器及如何使用_第5张图片

 

 

 

 


 

你可能感兴趣的:(MVC)