101

I've got the following action on an ApiController:

public string Something()
{
    return "value";
}

And I've configured my routes as follows:

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

In the beta, this worked just fine, but I just updated to the latest Release Candidate and now I'm seeing errors on calls like this:

The requested resource does not support http method 'GET'.

Why doesn't this work anymore?

(I suppose I could get rid of {action} and just make a ton of controllers, but that feels messy.)

Josh Schultz
  • 8,000
  • 9
  • 32
  • 39

11 Answers11

115

If you have not configured any HttpMethod on your action in controller, it is assumed to be only HttpPost in RC. In Beta, it is assumed to support all methods - GET, PUT, POST and Delete. This is a small change from beta to RC. You could easily decore more than one httpmethod on your action with [AcceptVerbs("GET", "POST")].

undefined
  • 33,537
  • 22
  • 129
  • 198
dinesh ravva
  • 1,176
  • 1
  • 8
  • 2
  • just encountered this, thanks for the fix, but curious, why do I have to do this with my custom methods, but not the default "Get" method? I have a Get method that was created by the template for the controller, but it's not decorated. is this just by convention because of the name Get? – SelAromDotNet Feb 26 '14 at 07:34
  • 5
    @Josh: Yes! When the name of the action method begins with "Get..." you don't have to mark it as a GET method. Read more here: http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api – Krisztián Balla Oct 06 '14 at 08:43
  • I did as suggested in the answer but now both of my calls, Get and Post, are being redirected to Get Action. Any help please? – Syed Ali Taqi Oct 16 '15 at 12:39
56

All above information is correct, I'd also like to point out that the [AcceptVerbs()] annotation exists in both the System.Web.Mvc and System.Web.Http namespaces.

You want to use the System.Web.Http if it's a Web API controller.

Hossein Narimani Rad
  • 31,361
  • 18
  • 86
  • 116
Eric Rini
  • 1,830
  • 15
  • 20
35

Although this isn't an answer to the OP, I had the exact same error from a completely different root cause; so in case this helps anybody else...

The problem for me was an incorrectly named method parameter which caused WebAPI to route the request unexpectedly. I have the following methods in my ProgrammesController:

[HttpGet]
public Programme GetProgrammeById(int id)
{
    ...
}

[HttpDelete]
public bool DeleteProgramme(int programmeId)
{
    ...
}

DELETE requests to .../api/programmes/3 were not getting routed to DeleteProgramme as I expected, but to GetProgrammeById, because DeleteProgramme didn't have a parameter name of id. GetProgrammeById was then of course rejecting the DELETE as it is marked as only accepting GETs.

So the fix was simple:

[HttpDelete]
public bool DeleteProgramme(int id)
{
    ...
}

And all is well. Silly mistake really but hard to debug.

Carl Sharman
  • 4,435
  • 1
  • 30
  • 29
  • 1
    If anyone is using url routing, try doing like [Route("{programmeId=programmeId:int}")] – sree Apr 05 '18 at 01:56
  • 1
    This was it for me. WebApiConfig -> MapHttpRoutes had -> routeTemplate: "api/{controller}/{id}", so a parameter of 'id' had to be used. – JsAndDotNet Jun 28 '18 at 10:29
  • 1
    your answer pointed me to my problem which was a little different I changed the name of one [FromUri] parameter for the method and didn't update it on the client side – Matus Nov 01 '18 at 16:34
30

If you are decorating your method with HttpGet, add the following using at the top of the controller:

using System.Web.Http;

If you are using System.Web.Mvc, then this problem can occur.

thomasb
  • 5,816
  • 10
  • 57
  • 92
Sohail xIN3N
  • 2,951
  • 2
  • 30
  • 29
15

This is certainly a change from Beta to RC. In the example provided in the question, you now need to decorate your action with [HttpGet] or [AcceptVerbs("GET")].

This causes a problem if you want to mix verb based actions (i.e. "GetSomething", "PostSomething") with non verb based actions. If you try to use the attributes above, it will cause a conflict with any verb based action in your controller. One way to get arount that would be to define separate routes for each verb, and set the default action to the name of the verb. This approach can be used for defining child resources in your API. For example, the following code supports: "/resource/id/children" where id and children are optional.

        context.Routes.MapHttpRoute(
           name: "Api_Get",
           routeTemplate: "{controller}/{id}/{action}",
           defaults: new { id = RouteParameter.Optional, action = "Get" },
           constraints: new { httpMethod = new HttpMethodConstraint("GET") }
        );

        context.Routes.MapHttpRoute(
           name: "Api_Post",
           routeTemplate: "{controller}/{id}/{action}",
           defaults: new { id = RouteParameter.Optional, action = "Post" },
           constraints: new { httpMethod = new HttpMethodConstraint("POST") }
        );

Hopefully future versions of Web API will have better support for this scenario. There is currently an issue logged on the aspnetwebstack codeplex project, http://aspnetwebstack.codeplex.com/workitem/184. If this is something you would like to see, please vote on the issue.

Jeremy
  • 502
  • 2
  • 9
8

Have the same Setup as OP. One controller with many actions... less "messy" :-)

In my case i forgot the "[HttpGet]" when adding a new action.

[HttpGet]
public IEnumerable<string> TestApiCall()
{
    return new string[] { "aa", "bb" };
}
Shaakir
  • 464
  • 5
  • 13
7

Same problem as above, but vastly different root. For me, it was that I was hitting an endpoint with an https rewrite rule. Hitting it on http caused the error, worked as expected with https.

Vern D.
  • 178
  • 1
  • 9
3

Replace the following code in this path

Path :

App_Start => WebApiConfig.cs

Code:

config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}/{Param}",
            defaults: new { id = RouteParameter.Optional,
                            Param = RouteParameter.Optional }
                          );
Kazem Maleki
  • 179
  • 3
  • 6
2

I got this error when running a query without SSL.

Simply changing the URL scheme of my request from HTTP to HTTPS fixed it.

Ben C.
  • 21
  • 2
  • @cizario I disagree - it does appear to be an attempt to answer the question. I'm voting "Looks OK" on this one. – EJoshuaS - Stand with Ukraine Nov 18 '20 at 15:40
  • @EJoshuaS-ReinstateMonica it appears more like a comment not a real answer to the question. based on the accepted answer and other answers below the issue seems not related to the schema. – cizario Nov 18 '20 at 16:17
  • @cizario Wrong answers are not very low quality - if you think that the answer is wrong, you should downvote. Please see: [Are blatantly wrong answers very low quality?](https://meta.stackoverflow.com/questions/345023/are-blatantly-wrong-answers-very-low-quality) – EJoshuaS - Stand with Ukraine Nov 18 '20 at 16:19
  • @EJoshuaS-ReinstateMonica you are right and i deleted my comment. – cizario Nov 18 '20 at 16:26
  • Ok, first, thanks!!!! Worked great!!! Now, about the question/answer, the fact is that using HTTP instead of HTTPS originates the error stated in the Question title, in fact I didn't read the actual question (body), but THIS is certainly a solution to the problem stated in question's title. – Gabriel G Nov 28 '22 at 00:06
1

I don't know if this can be related to the OP's post but I was missing the [HttpGet] annotation and that was what was causing the error, as stated by @dinesh_ravva methods are assumed to be HttpPost by default.

Pierrick Martellière
  • 1,554
  • 3
  • 21
  • 42
0

My issue was as simple as having a null reference that didn't show up in the returned message, I had to debug my API to see it.

Ninos
  • 224
  • 4
  • 18