IActionFilter返回一个新的Task <httpresponsemessage>永远不会返回</httpresponsemessage>

时间:2015-02-20 12:52:04

标签: c# asp.net-web-api async-await task action-filter

在ASP.NET Web API项目中,我有一个动作过滤器,用于检查模型状态错误并返回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();
    }
}

现在,出于某种原因,任何模型状态错误的请求都不会返回。它只是挂在那里。如果我调试,我会进入管道中的下一个过滤器,它以

开头
var result = await continuation(); 

如果我“跳过”该行,则调试器会退出“等待”模式,但似乎不再运行代码。

我认为所有这一切都是因为我在某种程度上误解了所有这些事情是如何相互作用的,但是尽管谷歌搜索和阅读了几个小时,我仍然无法弄清楚如何使这项工作正常。任何帮助 - 无论是理解还是错误修正 - 都深受赞赏。

1 个答案:

答案 0 :(得分:5)

你永远不会开始你的任务。使用Start构造函数时,需要调用Task。而不是调用构造函数然后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();
}