过滤器可以做什么呢?大概来说,它可以在action方法执行前、执行后做一些额外操作(比如权限验证),同时可以降低重复代码量,降低代码维护难度。
如果想在controller中使用action过滤器,可以实现这个接口:
IActionFilter
然后重写接口方法即可。来看有哪些:
void OnActionExecuted(ActionExecutedContext context);
Called after the action executes, before the action result.(操作执行之后,返回结果之前)
void OnActionExecuting(ActionExecutingContext context);
Called before the action executes, after model binding is complete.(操作执行之前,模型绑定完成之后)
两个方法官方注释写的很清楚,就是字面意思。
过滤器怎么用是知道了,但它如何帮助我们减少重复代码量呢?
假设我有10个action,而其中的5个需要用户登陆后才允许访问。那么我如果不使用过滤器,想要达成这个效果就需要在5个action内用相同的代码验证用户登录状态。但如果使用过滤器,那我只需要写一次代码就可以完成这个操作了:
public void OnActionExecuting(ActionExecutingContext context)
{
var controller = context.Controller.GetType();
string actionname = context.RouteData.Values["action"].ToString();
bool isNotLoginAttribute = controller.GetMethod(actionname).GetCustomAttributes(typeof(你定义的特性类), true).Length > 0;
if (isNotLoginAttribute)
return;
bool isOK = 验证登录权限的操作;
if (!isOK)
context.Result = BadRequest("未授权,拒绝访问!");
}
只需要把自定义的特性标注在需要的action(method、controller同理)上即可完成登录验证。
除了上面的,还有一种过滤器比较常用:
IExceptionFilter
字面意思,它是异常过滤器。它只有一个方法
void OnException(ExceptionContext context);
Called after an action has thrown an System.Exception.(在一个动作触发异常时调用)
重写这个方法,然后进入startup注册一个服务:
services.AddMvc(option =>
{
option.Filters.Add<自己写的异常过滤器>();
});
这样就可以实现全局异常捕捉,统一处理。
过滤器可以理解为core提供的钩子,满足对应条件就会自动触发,但可以自由决定如何去处理。这个做法其实就是AOP,但又不全是。今日时间不多,后面找时间再写一篇AOP吧。