.NET Core WebAPI 过滤器用法

过滤器定义

在.NET Web API中,过滤器(Filter)是一种可以在控制器方法执行前或执行后执行的代码。过滤器可以用于实现各种功能,例如身份验证、授权、异常处理、性能测量等等。


过滤器分类

以下是.NET Web API过滤器的常见用法

1.身份验证过滤器(Authentication Filter)用于验证请求的身份。可以使用基于令牌的身份验证或使用自定义的身份验证机制。

2.授权过滤器(Authorization Filter):用于授权请求。可以使用基于角色或基于声明的授权机制。

3.异常过滤器(Exception Filter):用于处理Web API方法中发生的异常。可以记录异常、发送电子邮件或通知开发人员。

4.动作过滤器(Action Filter):在执行控制器方法前或后执行自定义代码。可以用于检查参数、记录请求、执行缓存等等。

5.结果过滤器(Result Filter):在生成响应之前或之后执行自定义代码。可以用于修改响应、添加响应头、记录响应等等。


以下是如何在.NET Web API中使用过滤器

1.创建一个类并实现IAuthenticationFilter、IAuthorizationFilter、IExceptionFilter、IActionFilter或IResultFilter接口。

2.在WebApiConfig类的Register方法中注册过滤器。例如:config.Filters.Add(new MyFilter());

3.在过滤器类中实现需要执行的代码。


同步过滤器示例

以下是一个使用ActionFilterAttribute过滤器的示例代码:

public class LogActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        // 在执行控制器方法前执行的代码
        Debug.WriteLine("Executing action...");
    }
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
       // 在执行控制器方法后执行的代码
       if(actionExecutedContext.Exception==null)
       {
           //正常
       }
       else 
       {
           //异常
       }
    }
}

然后可以在控制器方法上使用该过滤器:

[LogActionFilter]
public IHttpActionResult Get(int id)
{
    // 控制器方法的代码
    return Ok();
}
//在此示例中,LogActionFilter将在Get方法执行之前和之后执行自定义代码。


异步过滤器示例

带有Async的接口就是异步

IAsyncAuthenticationFilter
IAsyncAuthorizationFilter
IAsyncExceptionFilter
IAsyncActionFilter

在 .NET Core 中,可以使用过滤器(Filter)来拦截请求和响应,以实现一些通用的功能,例如身份验证、日志记录、异常处理等。对于需要异步处理的过滤器,可以使用异步关键字来定义过滤器方法,并返回一个 Task 对象。


例如,下面是一个异步身份验证过滤器的示例:

public class AuthFilter : IAsyncAuthorizationFilter
{
    public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
    {
        // 异步身份验证逻辑
        bool isAuthenticated = await CheckAuthenticationAsync(context.HttpContext.User);
        if (!isAuthenticated)
        {
            context.Result = new UnauthorizedResult();
        }
    }
    private async Task<bool> CheckAuthenticationAsync(ClaimsPrincipal user)
    {
        // 异步身份验证逻辑
        // ...
    }
}

在上面的示例中,我们实现了一个异步的身份验证过滤器,该过滤器实现了 IAsyncAuthorizationFilter 接口,并覆盖了 OnAuthorizationAsync 方法。在该方法中,我们首先调用异步的 CheckAuthenticationAsync 方法来验证用户身份,然后根据验证结果设置响应的结果。


需要注意的是,对于异步过滤器方法,我们需要确保方法内部所有的异步操作都是异步的,不能阻塞线程。如果某些操作是同步的,则可以将其包装在 Task.Run 方法中,以确保它们在异步上下文中执行。


例如,如果在身份验证过滤器中需要进行一个 CPU 密集型的操作,则可以使用 Task.Run 方法来将其包装在异步任务中:


private async Task<bool> CheckAuthenticationAsync(ClaimsPrincipal user)
{
    // 异步身份验证逻辑
    // ...
    // 同步 CPU 密集型操作
    bool isAuthorized = await PerformAuthorizationAsync(user);
    // 异步身份验证逻辑
    // ...
    return isAuthorized;
}
private Task<bool> PerformAuthorizationAsync(ClaimsPrincipal user)
{
    // CPU 密集型操作
    // ...
}

总的来说,在 .NET Core 中使用异步过滤器可以提高应用程序的性能和可伸缩性,但需要注意异步操作的正确使用方式,以避免可能的线程阻塞和性能问题。


过滤器注册方式

1.除了特性注解(Attribute-based)

上面用例已经介绍过了 ,在接口加上 [过滤器类名]就可以了

2.用中间件(Middleware)管道的方式注册过滤器。

在使用中间件管道注册过滤器时,我们可以在 Startup.cs 文件中使用 app.UseFilter() 方法来将过滤器添加到管道中。例如,下面是一个注册身份验证过滤器的示例:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // 添加身份验证过滤器到管道
    app.Use(async (context, next) =>
    {
        //CheckAuthenticationAsync标题2里有
        bool isAuthenticated = await CheckAuthenticationAsync(context.User);
        if (!isAuthenticated)//验证失败返回401
        {
            context.Response.StatusCode = 401;
            return;
        }
        await next();
    });
    // 其他中间件
    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

在上面的示例中,我们使用了一个匿名的中间件来实现身份验证功能。在该中间件中,我们首先调用异步的 CheckAuthenticationAsync 方法来验证用户身份,然后根据验证结果设置响应的状态码或者继续执行下一个中间件。


需要注意的是,在使用中间件管道注册过滤器时,过滤器的作用范围会比特性注解方式更广泛,可以作用于整个应用程序或者某个请求的一部分。因此,我们需要确保过滤器的逻辑正确,并且不会影响其他中间件的正常执行。


果糖网