IActionFilter 返回一个新任务<HttpResponseMessage> 从不returns

IActionFilter returning a new Task<HttpResponseMessage> never returns

在 ASP.NET Web API 项目中,我有一个动作过滤器,用于检查模型状态错误和 returns Bad Request 状态代码(如果有的话)。它看起来像这样:

public class ValidationFilter : IActionFilter
{
    public Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext context,
                                                    CancellationToken cancellationToken,
                                           Func<Task<HttpResponseMessage>> continuation)
    {
        if(!actionContext.ModelState.IsValid)
        {
            return new Task<HttpResponseMessage>(() =>
                  actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest,
                                                            actionContext.ModelState);
        }
        return continuation();
    }
}

现在,出于某种原因,任何带有模型状态错误的请求永远不会returns。它只是挂在那里。如果我调试,我会到达管道中的下一个过滤器,它以

开头
var result = await continuation(); 

如果我 "Step Over" 该行,调试器会退出 "waiting" 模式,但似乎没有更多代码 运行.

我认为所有这一切都是因为我不知何故误解了所有这些东西是如何相互作用的,但尽管经过数小时的谷歌搜索和阅读,我仍然无法弄清楚如何使它正常工作。非常感谢任何帮助 - 无论是理解还是错误修复。

你永远不会开始你的任务。使用Task构造函数时需要调用Start。而不是调用构造函数然后 Start 一个更好的选择是使用 Task.Run:

if(!actionContext.ModelState.IsValid)
{
    return Task.Run(() =>
          actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest,
                                                    actionContext.ModelState);
}

在你的情况下,你的操作并没有真正的异步,所以你可以简单地使用 Task.FromResult 来创建一个任务,你得到的结果是同步的:

public Task<HttpResponseMessage> ExecuteActionFilterAsync(
    HttpActionContext context,
    CancellationToken cancellationToken,
    Func<Task<HttpResponseMessage>> continuation)
{
    if(!actionContext.ModelState.IsValid)
    {
        return Task.FromResult(actionContext.Request.CreateErrorResponse(
            HttpStatusCode.BadRequest, 
            actionContext.ModelState);
    }
    return continuation();
}