.net core 内使用过滤器

394 阅读2分钟

过滤器可以做什么呢?大概来说,它可以在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吧。