Question

I have an action filter that when used in certain specific conditions has to perform a web service call to ensure that the current state is valid. This initially seemed like an ideal candidate for async/await, but I have encountered a snag:

Assume a request to: /Test/FilteredAction

  • MyCustomActionFilter begins executing
    • The first "await" statement is reached
  • TestController.FilteredAction starts executing
  • MyCustomActionFilter resumes executing

Traditionally I would expect the action filter to resume executing and then complete before the controller action starts executing, but this does not happen.

Now I assume this is because I am using:

public class MyCustomActionFilter : ActionFilterAttribute 
{
    public override **async** void OnActionExecuting(FilterContext context) 
    {
        var foo = await WebServiceCall();
    }
}

So I think my question is: Is there an async-aware action filter class built into MVC 4, or should I just block on the calls in here?

Was it helpful?

Solution

MVC does not have an async-compatible action filter (but WebAPI does have one).

For now, I recommend you use blocking calls in OnActionExecuting. Hopefully MVC will have a better story in the future.

Update: You can vote here for the MVC team to add async filters.

OTHER TIPS

No, there is no asynchronous filter for MVC, but it is feasible.

ASP.NET MVC filters rely on the concept of being ordered, a filter is guaranteed (if specified. See the the Order property on the IMvcFilter interface) to execute In a certain order if specified.

The issues that have to be addressed in light of this are:

  • For existing filters that are not asynchronous (at least not implemented that way because there is no other way), do they get their own task or continue off the previous one? It's an important question to answer, as you have to weigh the benefit of not continuing the next filter on another thread vs. holding onto that thread while other requests could use it.

  • For filters that have the same order specified, do they execute in parallel or one after the other? Making the method async opens this possibility up even more (even though it could have been done before with a non-async signature) and its definitely an architectural change which could have an impact on performance as well as expected outcome. The answer here is not so simple and would have to be based on testing and backwards compatibility.

You cannot have async filters, but you can have async event handlers.

An async event handler can do the heavy async work, write to HttpApplication.HttpContext.Items, and then your sync filter can post-process or verify the results.

You can either register event handlers in Global.asax.cs, or create and register a HTTP module.

(All filters are executed between the PreRequest and PostRequest events.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top