Search code examples
c#asp.net-web-apiglobal-asaxasp.net-web-api-routing

Multiple HttpPost method in Web API controller


I am starting to use MVC4 Web API project, I have controller with multiple HttpPost methods. The Controller looks like the following:

Controller

public class VTRoutingController : ApiController
{
    [HttpPost]
    public MyResult Route(MyRequestTemplate routingRequestTemplate)
    {
        return null;
    }

    [HttpPost]
    public MyResult TSPRoute(MyRequestTemplate routingRequestTemplate)
    {
        return null;
    }
}

Here MyRequestTemplate represents the template class responsible for handling the Json coming through the request.

Error:

When I make a request using Fiddler for http://localhost:52370/api/VTRouting/TSPRoute or http://localhost:52370/api/VTRouting/Route I get an error:

Multiple actions were found that match the request

If I remove one of the above method it works fine.

Global.asax

I have tried modifying the default routing table in global.asax, but I am still getting the error, I think I have problem in defining routes in global.asax. Here is what I am doing in global.asax.

public static void RegisterRoutes(RouteCollection routes)
{
    routes.MapHttpRoute(
        name: "MyTSPRoute",
        routeTemplate: "api/VTRouting/TSPRoute",
        defaults: new { }
    );

    routes.MapHttpRoute(
        name: "MyRoute",
        routeTemplate: "api/VTRouting/Route",
        defaults: new { action="Route" }
    );
}

I am making the request in Fiddler using POST, passing json in RequestBody for MyRequestTemplate.


Solution

  • You can have multiple actions in a single controller.

    For that you have to do the following two things.

    • First decorate actions with ActionName attribute like

       [ActionName("route")]
       public class VTRoutingController : ApiController
       {
         [ActionName("route")]
         public MyResult PostRoute(MyRequestTemplate routingRequestTemplate)
         {
           return null;
         }
      
        [ActionName("tspRoute")]
        public MyResult PostTSPRoute(MyRequestTemplate routingRequestTemplate)
        {
           return null;
        }
      }
      
    • Second define the following routes in WebApiConfig file.

      // Controller Only
      // To handle routes like `/api/VTRouting`
      config.Routes.MapHttpRoute(
          name: "ControllerOnly",
          routeTemplate: "api/{controller}"               
      );
      
      
      // Controller with ID
      // To handle routes like `/api/VTRouting/1`
      config.Routes.MapHttpRoute(
          name: "ControllerAndId",
          routeTemplate: "api/{controller}/{id}",
          defaults: null,
          constraints: new { id = @"^\d+$" } // Only integers 
      );
      
      // Controllers with Actions
      // To handle routes like `/api/VTRouting/route`
      config.Routes.MapHttpRoute(
          name: "ControllerAndAction",
          routeTemplate: "api/{controller}/{action}"
      );