Question

I am creating a restful api with ASP .NET Web Api and I am having trouble with setting up the routing.

Question 1: I am trying to set up a custom delete route. If I name my the action on my controller "DeleteTargetFromApplication" it works perfectly but if I name the action "RemoveTargetFromApplication" it gives me a "The requested resource does not support http method 'DELETE'" error. I change nothing other than the name. The route I use is set up like this:

config.Routes.MapHttpRoute(
                name: "PesticideRemoveTargetFromApplication",
                routeTemplate: "Pesticide/Applications/{id}/Targets/{targetId}",
                defaults: new { controller = "Applications", action = "DeleteTargetFromApplication" },
                constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Delete) }
            )

Is there something that I don't get about how Web Api matches routes?

Question 2: I have all default routes for Get, Post, Put, Delete, Patch. Above the defaults I create any special routes above where the defaults are setup. For some reason, when I add:

config.Routes.MapHttpRoute(
                name: "PesticideGetTargetsForApplication",
                routeTemplate: "Pesticide/Applications/{id}/Targets",
                defaults: new { controller = "Applications", action = "GetTargetsForApplication" },
                constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Get) }
            );

above the defaults, it is saying I have two actions that match, the "GetTargetsForApplication" action and the the default "Get" action I put on all controllers. Why is it seeing both of these actions even if I am specifically telling it which action to use. The route templates are clearly different being "Applications/:id/Targets" and "Applications" respectively. Why are these getting mixed up?

Was it helpful?

Solution

On Question 1:

The routing engine is convention based and determines the allowable HTTP verbs from the name of method (action). So thats why DeleteTargetFromApplication works.

A simple work around is to add [HttpDelete] to the definition of RemoveTargetFromApplication.

From http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api

To find the action, Web API looks at the HTTP method, and then looks for an action whose name begins with that HTTP method name. For example, with a GET request, Web API looks for an action that starts with "Get...", such as "GetContact" or "GetAllContacts". This convention applies only to GET, POST, PUT, and DELETE methods. You can enable other HTTP methods by using attributes on your controller. We’ll see an example of that later.

OTHER TIPS

I think I have figured this out. The problem was that when I was calling the Pesticide/Applications/:id/Targets url it was working but any other GETs were getting confused and it had to do with the above answer. It was checking for any action that started with "Get" and had a similar signature and was finding multiple. What I did was add a default action of "Get" to my default routes so that it was only using that particular action on default routes. It takes away a little of the functionality of the web api route matching but it allows for separation of actions in the same controller that look similar but have different names

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top