Reputation: 678
I would like to execute an API call via attribute before a route execution. I created a customer action filter and use the OnExecuting() override function.
Within the function I awaite an async API call to another server. However, while debugging I notice the Route executes before that async call is complete. How can I accomplish this.
[CustomAttribute("Stuff")]
[Route("MyRoute")]
public async Task<IHttpActionResult> MyRoute()
{
await anotherAsyncFunction();
return Ok();
}
And the definition of the Custom Action Filter.
public class CustomAttribute : ActionFilterAttribute
{
private string att;
public CustomAttribute(string a)
{
att = a;
}
public async override void OnActionExecuting(HttpActionContext actionContext)
{
await MyFirstAsyncFunction();
}
}
Unfortunately this doesn't finish before the route code executes.
Upvotes: 1
Views: 1865
Reputation: 456417
I created a customer action filter and use the OnExecuting() override function.
As commenters have noted, this is due to the use of async void
, which does not provide an easy way for callers to wait for asynchronous operations to complete. This is one reason why my async best practices article includes the advice "avoid async void".
I would like to execute an API call via attribute before a route execution.
Unfortunately, ASP.NET MVC does not support asynchronous filters (they do, however, work just fine on ASP.NET Core). AFAIK, there are no plans to add this to the existing ASP.NET MVC product. Your options are to either execute the code manually (i.e., within the action, instead of using an attribute), or make your filter synchronous.
I just did HttpResponseMessage response = client.PostAsJsonAsync("/api/rotue/", res).Result;
This is the sync-over-async anti-pattern. It just happens to work in this case. It would be better to replace HttpClient
(which is async-only) with WebClient
(which supports sync).
Upvotes: 1