7

So, we've got an MVC project that has been upgraded through the different versions of MVC from 1 through to 4.

Now we have a controller method:

public async Task<ActionResult> IndexAsync()

so if we go to http://somedomain.xyz/WhicheverController or http://somedomain.xyz/WhicheverController/Index, we are greeted with a 404.

http://somedomain.xyz/WhicheverController/IndexAsync routes to the method just fine.

What's gone wrong with our routing?

1
  • Where is your routing? There is no convention that maps names to async methods Commented Nov 26, 2013 at 16:54

3 Answers 3

6

I believe that your example will work if you derive your Controller from AsyncController instead.

public class MyController:AsyncController
{
    public async Task<ActionResult> IndexAsync()
    {
       return View(); //view called "Index.cshtml", not "IndexAsync.cshtml"
    }
}

So now you can hit ~/My/Index without the Async suffix, despite Async appearing in the controller name.

This is a relic from the previous MVC asynchronous controller method, and usually required an IndexComplete method to work, but with Task based async controller method, the matching XxxxComplete method is not required, but the Async convention is observed.

The actual implementation of AsyncController is rather sparse:

public abstract class AsyncController : Controller
{
}

So somewhere in the MVC stack, the type of the controller is tested, and special routing magic is turned on.

Sign up to request clarification or add additional context in comments.

Comments

3

There is no convention that maps asynchronous actions to methods with the Async suffix. If you want to use the Async suffix in an action's name, you will have to modify your route.

Simply changing your method's return type to async Task<ActionResult> is enough to execute the action asynchronously.

The Async suffix is simply a naming convention. It isn't expected or enforced by any of the MVC frameworks.

Example

The following action works asynchronously using the default routing

public class HomeController : Controller
{
    public async Task<ActionResult> Index()
    {
        await Task.Delay(1000);
        ViewBag.Message = "Modify this template to jump-start blah .. blah";

        return View();
    }
    ...
}

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", 
                            id = UrlParameter.Optional }
        );
    }
}

Comments

0

Routing works just fine, in asp.net mvc 5 you don't need Async suffix for action anymore and you should remove it.

This convention was needed just for linking two actions that execute one job asynchronously (action method and action result). With new asyncronous model for in asp.net mvc 5 you don't need this Async convention anymore. Just like inheriting from AsyncController.

4 Comments

Yes, but why doesn't the convention work anymore? Btw. we're on MVC4
I think this convention worked when you derived from AsyncController. In asp.net mvc 5 you don't need to do it and routing works like with other actions.
According to Using Asynchronous Methods in ASP.NET MVC 4 (asp.net/mvc/tutorials/mvc-4/…), "Appending 'Async' is not required but is the convention when writing asynchronous methods."
Yes it's convention for writing async methods, not for routing. Look at the following controller: github.com/RickAndMSFT/Async-ASP.NET/blob/master/Mvc4Async/…. Let's say I go to /Home/Products, then which of actions should be executed? ProductsAsync or Products?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.