.NET MVC在路由之前在Attribute中执行异步任务

时间:2016-03-21 13:40:26

标签: c# asp.net-mvc asp.net-web-api2

我想在路由执行之前通过属性执行API调用。我创建了一个客户操作过滤器并使用OnExecuting()覆盖函数。

在函数中,我等待对另一台服务器的异步API调用。但是,在调试时我注意到在异步调用完成之前Route已执行。我怎样才能做到这一点。

    [CustomAttribute("Stuff")]
    [Route("MyRoute")]
    public async Task<IHttpActionResult> MyRoute()
    {
        await anotherAsyncFunction();
        return Ok();
    }

自定义操作过滤器的定义。

public class CustomAttribute : ActionFilterAttribute
{
    private string att;
    public CustomAttribute(string a)
    {
        att = a;
    }


    public async override void OnActionExecuting(HttpActionContext actionContext)
    {


        await MyFirstAsyncFunction();


    }
}

不幸的是,在路线代码执行之前,这还没有完成。

1 个答案:

答案 0 :(得分:0)

  

我创建了一个客户操作过滤器并使用OnExecuting()覆盖函数。

正如评论者所指出的,这是由于async void的使用,它没有为调用者提供等待异步操作完成的简便方法。这就是为什么我的async best practices article包含建议&#34;避免异步无效&#34;。

的原因之一。
  

我想在路由执行之前通过属性执行API调用。

不幸的是,ASP.NET MVC不支持异步过滤器(但它们可以在ASP.NET Core上运行得很好)。 AFAIK,没有计划将其添加到现有的ASP.NET MVC产品中。您可以选择手动执行代码(即,在操作中,而不是使用属性),或使您的过滤器同步。

  

我刚做了HttpResponseMessage response = client.PostAsJsonAsync(&#34; / api / rotue /&#34;,res).Result;

这是sync-over-async anti-pattern。它只是发生才能在这种情况下工作。最好将HttpClient(仅限异步)替换为WebClient(支持同步)。