1

I'm working in an MVC5 application that will be handling some intense IO operations. So we are converting methods to use the async/await TPL stuff.

Prior to the async/await changes I registered a custom IAsyncActionInvoker which changes the Json ActionResult to a JsonNet ActionResult like in this example:

Using JSON.NET as the default JSON serializer in ASP.NET MVC 3 - is it possible?

The trouble comes in when changing to use async/await Task where the JsonNet ActionResult is never executed. Does anyone know how to maintain this implementation while moving to async/await Task ?

 public class CustomActionInvoker : AsyncControllerActionInvoker
{
    protected override ActionResult InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters)
    {
        ActionResult invokeActionMethod = base.InvokeActionMethod(controllerContext, actionDescriptor, parameters);

        if (invokeActionMethod is JsonResult)
        {
            return new JsonNetResult(invokeActionMethod as JsonResult);
        }

        return invokeActionMethod;
    }
}




 public class HomeController : Controller
{
    // THIS WORKS!
    public ActionResult Test()
    {
        return Json(new
        {
            Property1 = "blah",
            Property2 = "test"
        }, JsonRequestBehavior.AllowGet);
    }

    // THIS DOES NOT FIRE MY CUSTOM ACTION INVOKER
    // IT RUNS THE DEFAULT
    public async Task<ActionResult> Test()
    {
        await Task.Run(() =>
        {
            Thread.Sleep(1000);
        });

        return Json(new
        {
            Property1 = "blah",
            Property2 = "test"
        }, JsonRequestBehavior.AllowGet);
    }
}

Any help would be greatly appreciated guys!

Community
  • 1
  • 1
Dan D
  • 2,493
  • 15
  • 23
  • Have you tried overriding BeginInvokeActionMethod and EndInvokeActionMethod on your CustomActionInvoker? – danludwig Feb 04 '14 at 00:51
  • I just saw that after reading this comment, going to try overriding both of those and see if I get the expected result, thanks! @danludwig – Dan D Feb 04 '14 at 02:05
  • 1
    I would have answered this but apparently I can't, so after @danludwig commented on my question, I found the correct answer. I assumed that since the Begin/End Asynchronous methods were considered "old" in favor of the TPL async/await methods that implementing the async/await pattern would keep us from having to override the Begin/End InvokeActionMethod methods in the AsyncControllerActionInvoker (thought it was only there for backward compatibility). So the answer is to override the EndInvokeActionMethod. – Dan D Feb 04 '14 at 02:39
  • Once you get more reputation you can come back and answer this question. Glad I could help you find it. – danludwig Feb 04 '14 at 13:23

1 Answers1

1

Coming back to answer this finally, the answer is to override InvokeActionMethod and EndInvokeActionMethod to handle both Synchronous and Asynchronous ActionResults.

protected override ActionResult EndInvokeActionMethod(IAsyncResult asyncResult)
{
    var actionResult = base.EndInvokeActionMethod(asyncResult);
    if(actionResult is JsonResult)
    {
        return new JsonNetResult(actionResult as JsonResult);
    }
    return actionResult;
}
Dan D
  • 2,493
  • 15
  • 23