Async action filter in MVC 4
Asked Answered
I

3

33

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?

Impoverish answered 18/9, 2012 at 17:50 Comment(2)
Have you tried to apply method described in ayende's blog post?Earplug
I've recently published a library that adds proper support for async filters (heavily based on code in from ASP.NET MVC Core). Source is also available here: github.com/jdaigle/Hydrogen.Extensions.Mvc5.Directoire
U
43

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.

Ultimo answered 18/9, 2012 at 18:22 Comment(7)
I wish they would support razor ootb with web API and then we could do away with asp.net mvc altogether!Ilmenite
@StephenCleary:I think a non-async filter works fine on a async action. Can you show me a scenario that needs a async-compatible action filter? Thanks.Exum
+1 @DannyChen, filter that calls a service to verify something is exact example of why you want asynchronous support for filters. The issue is not that synchronous filter does not work, but rather async filter would work much better.Cockloft
I spent like all day trying to get async code to work inside the "OnActionExecuting" method. Kept getting deadlocks. We really need support for async here. The example I'm trying to do is check and update a distributed cache.Stolon
@DannyChen A diagnostic filter that adds a additional delay time to the processed request without starving threads.Rosewater
The "vote here" link in the answer here is broken - is there any recent news on support for this? If there's still a place to vote (or a GitHub issue to +1 or something), I'd throw mine on it. I googled for a bit but couldn't come up with anything.Gunflint
@RobHruska async filters for MVC will work on ASP.NET vNext. AFAIK they're not planning on adding it to the current branch of MVC.Ultimo
M
1

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.)

Millpond answered 30/6, 2020 at 5:53 Comment(0)
R
0

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.

Raquel answered 29/9, 2012 at 14:9 Comment(1)
I don't think it's that complicated. Filters can short-circuit results, so you have no choice but to run them sequentially, whether they are sync or async. This is the existing behavior, and therefore no backwards compatibility issues can arise.Janessajanet

© 2022 - 2024 — McMap. All rights reserved.