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

Multiple actions for the same HttpVerb


I have a Web API controller with the following actions:

    [HttpPut]
    public string Put(int id, JObject data)

    [HttpPut, ActionName("Lock")]
    public bool Lock(int id)

    [HttpPut, ActionName("Unlock")]
    public bool Unlock(int id)

And the following routes mapped:

        routes.MapHttpRoute(
            name: "Api",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        routes.MapHttpRoute(
            name: "ApiAction",
            routeTemplate: "api/{controller}/{action}/{id}"
        );

When I make the following requests everything works as expected:

PUT /api/items/Lock/5
PUT /api/items/Unlock/5

But when I attempt to make a request to:

PUT /api/items/5

I get the following exception:

Multiple actions were found that match the request:
    Put(int id, JObject data)
    Lock(int id)
    Unlock(int id)

I tried adding an empty action name to the default route but that did not help:

[HttpPut, ActionName("")]
public string Put(int id, JObject data)

Any ideas how I can combine default RESTful routing with custom action names?

EDIT: The routing mechanism is not confused by the choice of controller. It is confused by the choice of action on a single controller. What I need is to match the default action when no action is specified. Hope that clarifies things.


Solution

  • With the help of Giscard Biamby, I found this answer which pointed me in the right direction. Eventually, to solve this specific problem, I did it this way:

    routes.MapHttpRoute(
        name: "ApiPut", 
        routeTemplate: "api/{controller}/{id}",
        defaults: new { action = "Put" }, 
        constraints: new { httpMethod = new HttpMethodConstraint("Put") }
    );
    

    Thanks @GiscardBiamby