WebAPI – Multiple actions were found that match the request

WebAPI looks very suitable for exposing RESTful services for any web based application. So, during a recent implementation of WebAPI on a project I was receiving the Multiple actions were found that match the request exception.

To get some context below was my setup:

The route configuration:

public static class WebApiConfig {
    public static void Register( HttpConfiguration config ) {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

The controller:

public class PIAPIController : ApiController {
    private readonly IFilterRepository repository = new FilterRepository( );

    public List<AutoCompleteItems> GetCampusList(string term = null ) {
        // business logic...
        return nv;
    }
    public List<AutoCompleteItems> GetDivisionList( string term = null ) {
        // business logic...
        return nv;
    }
}

The controller in issue has multiple Get actions with varying names, since all of this actions were addressing a similar unit of filters I had grouped them together in the same controller.

After Googling around for a while I came across the following useful answers on StackOverflow:

http://stackoverflow.com/a/12185249

http://stackoverflow.com/a/12703423

After changing the route config to

public static void Register( HttpConfiguration config ) {
    config.Routes.MapHttpRoute(
        name: "DefaultApiWithID",
        routeTemplate: "api/{controller}/{id}",
        defaults: null
    );
    config.Routes.MapHttpRoute( "DefaultApiWithAction", "Api/{controller}/{action}" );
}

and decorating the action names with [ActionName("uniqueactionname")], the modifications did not help address the error.

But finally changing the order of routes in the route configuration solved the issue.

public static void Register( HttpConfiguration config ) {
    config.Routes.MapHttpRoute( "DefaultApiWithAction", "Api/{controller}/{action}" );
    config.Routes.MapHttpRoute(
        name: "DefaultApiWithID",
        routeTemplate: "api/{controller}/{id}",
        defaults: null
    );
}

Lesson Learned: Move more greedy routes to the end.

comments powered by Disqus