Mvc构建自定义的过滤器
实现自定义的过滤器只需要继承FilterAttrbute类,并实现IActonFilter,IResultFilter接口,为了这个过程更加容易,可以直接继承ActionFilterAttribute基类:
ActionFilterAttribute:是一个抽象类,其中包含4个可以重写的方法:
1.OnActionExecuting:
该方法在使用过滤器特性标记的任何动作方法之前执行,基类的所以方法都可以使用上下文对象作为参数:上下文对象是ActionExecutingContext类的实例:
ActionParameters:传送至动作的所以参数列表
ActionDescriptor: 包含与即将执行的动作和控制器的相关的所以信息,如动作名称,控制器名。类型(后面两个信息保存在ControllerDescriptor属性中)
Controller:包含与即将执行的动作的控制器实例
RouteData:将请求传送至动作的路由的所有低级细节(所以url 和数据标记)
HttpContext:http请求的当前执行上下文
ActionResult:取消动作执行:
2.OnActionExecuted:
动作方法结束是,框架将调用这个方法,该方法包含ActionExecuting 参数,同时有增加一些参数:
Exceptin:包含一个在动作方法执行过程中可能抛出异常
ExceptionHandled:这个一个boolean值,指示是否处理了Exception属性指定异常(只有在同一个动作方法之后执行多个过滤器是才有意义)
Result:动作方法已返回的动作结果
**:如果提供了异常并且你的过滤器处理异常,ExceptionHandler属性值设置true,通知其他该链中其他过滤器。
Canceled:其他过滤器在OnExecuting中设置了Result属性取消执行动作方法是,该属性的值为true.如果过滤器依赖在被执行的动作逻辑,那么就在这个操作前验证这个属性是否为false非常有必要。
3.OnResultExecuting;
在ActionResult对象调用的方法返回之前,框架会调用OnResultExecuting方法,该方法接受一个ResultExecutingContext类型对象,除上下文标准属性(controller,httpcontext,routedata),ResultExecutingContext还在Result属性中包含了将执行的动作结果引用,还提供了个Cancel属性,过滤器可以通过该属性阻止执行动作结果。
4.OnResultExecuted:
在动作执行之后调用,这个对象参数没有什么区别,就是不能设置Result属性,因为它已经执行结束,
示例:
public class LoggingFilterAttribute : ActionFilterAttribute
{
private string _logMessage = string.Empty;
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// base.OnActionExecuting(filterContext);
string message = string.Format("Executing {0}.{1} with {2} Parameters<br/>",
filterContext.ActionDescriptor.ControllerDescriptor.ControllerName,
filterContext.ActionDescriptor.ActionName,
filterContext.ActionParameters.Count);
_logMessage = message;
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
//base.OnActionExecuted(filterContext);
string message = string.Format("Finished executing action {0}.{1} with result {2} <br/>",
filterContext.ActionDescriptor.ControllerDescriptor.ControllerName,
filterContext.ActionDescriptor.ActionName,
filterContext.GetType().Name );
_logMessage = _logMessage + message;
}
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
//base.OnResultExecuting(filterContext);
string message = string.Format("Starting to execute result {0} <br/>",
filterContext.Result.GetType().Name);
_logMessage = _logMessage + message;
}
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
// base.OnResultExecuted(filterContext);
string message = string.Format("Finished executing result {0} <br/>",
filterContext.Result.GetType().Name);
filterContext .HttpContext .Response .Output .WriteLine("<div class='trace page'>"+_logMessage+message+"</div>");
}
}
[LoggingFilter]
public ActionResult ViewTest()
{
return View();
}
过滤器执行顺序:
1.最先执行通过在控制器中重写的OnActionExecuting和OnActionExecuted方法定义的所有过滤器
2.然后使用order属性的值,对所有基于特性定义的过滤器进行排序,如果没有指定顺序,将-1作为过滤器的执行顺序值,在同一范围里不能有多个过滤器具有相同的顺序
3.如果在不同的范围内定义的过滤器具有相同顺序,在类型级别上定义的过滤器将在动作级别上定义的过滤器之前执行。