Asp.net web api 异步操作筛选器:异步&;ASP.NET WEB API中的AuthorizeAttribute

Asp.net web api 异步操作筛选器:异步&;ASP.NET WEB API中的AuthorizeAttribute,asp.net-web-api,async-await,action-filter,Asp.net Web Api,Async Await,Action Filter,我在一个类中拥有身份验证逻辑,该类派生自System.Web.Http.AuthorizeAttribute(在身份验证方法上被重写)。我从该方法调用DB,我希望该调用是异步的(幸运的是,新的ADO.NET异步API允许这样做) 然后我将此属性应用于控制器,使对它的所有调用都通过身份验证过滤器。到目前为止还不错 但是这样做我遇到了以下问题。框架(ASP.NET Web API)似乎不知道我的意图是什么:)它似乎在我的筛选器的OnAuthorization方法完成之前(从异步调用返回)继续执行控制

我在一个类中拥有身份验证逻辑,该类派生自System.Web.Http.AuthorizeAttribute(在身份验证方法上被重写)。我从该方法调用DB,我希望该调用是异步的(幸运的是,新的ADO.NET异步API允许这样做)

然后我将此属性应用于控制器,使对它的所有调用都通过身份验证过滤器。到目前为止还不错

但是这样做我遇到了以下问题。框架(ASP.NET Web API)似乎不知道我的意图是什么:)它似乎在我的筛选器的OnAuthorization方法完成之前(从异步调用返回)继续执行控制器的操作。。因此,框架的例外情况是“在所有未完成的异步操作完成之前,请求处理已完成…”

有什么现成的方法来解决这个问题吗

谢谢


另外,我的直觉告诉我,我正在创建一个定制的动作过滤器。。然后,我需要重写ExecuteActionFilterAsync,并在那里进行身份验证,自己处理所有与任务相关的内容,而不需要框架方面的帮助……)

好的,下面是我的想法(在用反光镜看了一眼引擎盖下):

public class SecurityFilterAttribute:FilterAttribute,IAAuthorizationFilter
{
公共异步任务ExecuteAuthorizationFilterAsync(HttpActionContext actionContext、CancellationToken CancellationToken、Func continuation)
{ 
等待身份验证(actionContext);
返回actionContext.Response??等待继续();
}
身份验证专用异步任务(HttpActionContext actionContext)
{
//一些冗长的I/O操作(XXXAsync/await)
}
}
这样,当应用于控制器/操作时,所有逻辑都将以正确的顺序执行,同时在I/O期间保持线程畅通。不过,这并不十分尊重取消。但对我来说应该没问题


不管怎样,我真的很想知道是什么让Web API的创作者们不走类似的路。。。Ideas?

使用
IAsyncAuthorizationFilter
并异步实现接口


公共异步任务OnAuthorizationAsync(AuthorizationFilterContext actionContext)

框架提供给您的所有筛选器接口都支持异步。我假设您使用的是公开同步API的默认实现。按照下面答案中的建议使用
IAuthorizationFilter
。我相信这仅适用于.NET Core。因为OP提到了System.Web.Http.AuthorizeAttribute,所以我猜他说的是Web API或MVC。
public class SecurityFilterAttribute : FilterAttribute, IAuthorizationFilter
{
    public async Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
    { 
        await OnAuthentication(actionContext);

        return actionContext.Response ?? await continuation();
    }

    private async Task OnAuthentication(HttpActionContext actionContext)
    {
         //some lengthy I/O operations (XXXAsync/await)
    }
}