.Net MVC 常用的4种过滤器:
- Action过滤器(IActionFilter):行为过滤器
- Result过滤器(IResultFilter):结果过滤器
- Exception过滤器(IExceptionFilter):异常过滤器
- Authorization过滤器(IAuthorizationFilter): 权限效验过滤器
Action过滤器:在Action执行之前和执行之后调用。
Result过滤器:在结果之前和之后调用。
Exception过滤器:在发生异常时调用。
Authorization过滤器:身份验证时调用。
过滤器作用:
一般用于记录日志、异常处理、身份验证、行为记录等。
如何实现过滤器:
- Action过滤器和Result过滤器的实现继承于抽象类ActionFilterAttribute,所以想使用这两个过滤器需要去实现这个抽象类,重写它的方法即可。抽象类ActionFilterAttribute中有继承FilterAttribute类,可以使用标记特性,实现控制器或方法局部过滤。
- Exception过滤器要实现接口IExceptionFilter,这个接口中有异常过滤的方法。当我们需要在控制器或者方法上去单独局部实现异常过滤器,使用标记方法这种特性时需要继承FilterAttribute类。
- Authorization过滤器要实现接口IAuthorizationFilter,这个接口中有权限过滤的方法。当我们需要在控制器或者方法上去单独局部实现权限过滤器,使用标记方法这种特性时需要继承FilterAttribute类。
Demo演示:
由于Action过滤器和Result过滤器的实现都继承于抽象类ActionFilterAttribute,在这里简单演示Action和Result过滤器。
1 建立一个mvc web项目,直接使用mvc的模版即可。
2.因为ActionFilterAttribute是抽象类,所以要准备一个类来继承实现它,重写抽象类的方法。
public class MyActionFilterAttribute: ActionFilterAttribute
{
public string Name { get; set; }
//在Action执行之前先执行此方法
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
filterContext.HttpContext.Response.Write("OnActionExecuting---" + Name + "<br/>");
}
//在Action执行之中执行此方法
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
filterContext.HttpContext.Response.Write("OnActionExecuted---" + Name+"<br/>");
}
//在Action执行结果前执行此方法
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
base.OnResultExecuting(filterContext);
filterContext.HttpContext.Response.Write("OnResultExecuting---" + Name + "<br/>");
}
//在Action执行结果后执行此方法
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
base.OnResultExecuted(filterContext);
filterContext.HttpContext.Response.Write("OnResultExecuted---" + Name + "<br/>");
}
}
3 局部实现过滤
3.1在控制器上实现Action Result过滤,直接在方法上标记过滤器即可,过滤器名称MyActionFilterAttribute可以省略Attribute,用MyActionFilter标记即可。
public class HomeController : Controller
{
[MyActionFilter(Name = "Home/Index 方法过滤")] //Attribute标记法
public ActionResult Index()
{
HttpContext.Response.Write(" Action方法执行中<br/>");
return View();
}
}
3.2 方法标记过滤结果
3.3 如果想整个控制器的方法都要实现过滤,可以在控制器上标记过滤
[MyActionFilter(Name ="Home 控制器过滤")] //控制器过滤器
public class HomeController : Controller
{
public ActionResult Index()
{
HttpContext.Response.Write(" <font color='red'>Action方法执行中</font><br/>");
return View();
}
}
3.4 控制器标记过滤结果
3.5 如果控制器和方法都标记了过滤器,那么近水楼台先得月,会选择方法上的过滤器,也可以设置打开所有过滤器设置,将两个过滤器都触发,这个设置默认是关闭的。
4 全局过滤
4.1 如果想把所有Action Result都加上过滤,可以去给每个控制器加上标记,但这样太麻烦了,我们可以在FilterConfig中添加一个全局的过滤器。
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
//添加Action Result全局过滤器
filters.Add(new MyActionFilterAttribute() { Name= "全局Action Result过滤器" });
//添加Exception全局过滤器
//filters.Add(new MyExceptionFilterAttribute(){ Name= "全局Exception过滤器" });
//添加Authorization全局过滤器
//filters.Add(new MyAuthorizationFilterAttribute(){ Name= "全局Authorization过滤器" });
}
}
4.2 将之前的控制器和方法上的过滤器标记屏蔽掉。
public class HomeController : Controller
{
public ActionResult Index()
{
HttpContext.Response.Write(" <font color='red'>Action方法执行中</font><br/>");
return View();
}
}
4.3 全局过滤器结果
4.4 如果全局 控制器 方法上都标记了过滤器,实际过滤器是方法上的,也可以将所有过滤器都打开触发,这个设置默认关闭,需要可以打开。
剩下两种过滤器这里就不再详细说了,代码中有演示,有兴趣可以看看,项目代码:
https://github.com/wangqilong1225/C-Sharp-Test/tree/master/FilterDemo