1

I am make POST call into my Web API using Postman. I get the error: "The requested resource does not support http method 'GET'." I am not making a GET call. If I do call one of my GET methods, it works fine and returns the expected result.

My controller class:

[RoutePrefix("api/login")]
    public class LoginController : ApiController
    {
        ModelContext db = new ModelContext();

        [HttpPost]
        [Route("validate")]
        public HttpResponseMessage Validate([FromBody] LoginViewModel login)
        {
            try
            {

                    var message = Request.CreateResponse(HttpStatusCode.OK);
                    return message;
            }
            catch (Exception ex)
            {
                var message = Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex.Message);
                return message;
            }
        }        

    }

I have the Web API running locally and call with this URL:

http://localhost:44303/api/login/validate

This url returns:

<Error>
<Message>
The requested resource does not support http method 'GET'.
</Message>
</Error>

My routing in WebApiConfig.cs

config.MapHttpAttributeRoutes();

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

While this controller message returns HttpResponseMessage, I have tested by changing the response to "string" and just returning a string value, but I get the same error. I have read through so many SO posts but none appear to fix my issue. I am at a total loss to explain this behavior. I appreciate any ideas.

EDIT I have tested GETs in other controllers and they are returning data as expected.

EDIT FOR CONTEXT 6/3/2020 This method in the default ValuesController works:

[Route("api/values")]
public IEnumerable<string> Get()
{
   return new string[] { "value1", "value2" };
}

These 2 methods in the SAME controller do not work:

// GET api/values/5
public string Get(int id)
{
  return "value";
}

// POST api/values
public void Post([FromBody]string value)
{
}

EDIT #2 6/3/2020 Now all of my api methods are working for the default ValuesController. I do not know why. My custom POST methods in other controllers such as the Post method above are still not working. Here is my current WebApiConfig.cs:

public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

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

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

I do not have any middleware or special routing that I know of. Any exception handling would be simple try-catch.

I am trying to use attribute routing vs convention but that seems to be an issue.

Nkosi
  • 235,767
  • 35
  • 427
  • 472
Ryan
  • 650
  • 3
  • 15
  • 49
  • `FromBody` requires payload. Where is it? Are you using Postman? – T.S. May 31 '20 at 17:50
  • I am using Postman, and just passing a dummy username and password as json – Ryan May 31 '20 at 18:06
  • Do you have any middleware in your solution or any type of customization that can mess up routing or change request headers for example? – Yevgeniy.Chernobrivets Jun 03 '20 at 16:17
  • Are you sure that you using postman correctly. Your Action is indeed a POST action and no Action GET exists on your API – apomene Jun 03 '20 at 16:17
  • Do you have any additional middleware which might be rewriying the request? Like authorization redirect? or exeption handling? – Stefan Jun 03 '20 at 16:17
  • Have you tried creating new solution and adding only parts which you posted to it and test on it? – Yevgeniy.Chernobrivets Jun 03 '20 at 16:19
  • maybe try to remove http from url or swap it with https. You can also check your trafic with e.g fiddler or even windows sniffer to check what was called in between, there could be some redirection which calls get method due to some settings – sTrenat Jun 03 '20 at 16:26
  • Also, you may see some details in postman console (ctrl+alt+c) – sTrenat Jun 03 '20 at 16:29
  • I added info into my question – Ryan Jun 03 '20 at 16:51
  • @RomanMarusyk I took out the config.Routes and restored the original. The Posts are not working and in fact return "HTTP Error 400. The request hostname is invalid" – Ryan Jun 03 '20 at 17:21
  • Ok, great. This is different error. You need to update IISExpress applicationhost.config. Look at [this](https://stackoverflow.com/questions/17223404/400-bad-request-when-access-asp-net-web-api-via-computer-name-on-iisexpress) or [this](https://stackoverflow.com/questions/28699538/bad-request-invalid-hostname-with-asp-net-webapi-project-in-visual-studio-2013) – Roman Marusyk Jun 03 '20 at 17:23
  • 1
    Why there is else without if?Anything I am missing? – MBB Jun 03 '20 at 17:25
  • @mahesh_b thanks for pointing that out. When I cut and pasted the code for this question, I had removed a bool check for simplicity but forgot to remove the else. – Ryan Jun 03 '20 at 17:31
  • @Ryan any updates? – Roman Marusyk Jun 03 '20 at 18:01
  • @Ryan you are mixing attribute routing and convention-based routing, which is causing route conflicts. – Nkosi Jun 04 '20 at 00:19
  • @Ryan how do you test the call to `http://localhost:44303/api/login/validate`? Using what? Chances are that you are actually making a GET request on a controller that only has a POST action available via attribute routing. – Nkosi Jun 04 '20 at 00:21
  • @Nkosi I am testing by calling the method via Postman, and sending a json body with a dummy username and password. I dont understand what you mean about making a GET request on a controller that only has a POST action. I am specifying POST in Postman and the method decoration. – Ryan Jun 04 '20 at 03:10

1 Answers1

0

You don't need to create a route table by HttpMethods because you have [HttpPost] attribute.

Replace all config.Routes.MapHttpRoute by

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

It's preferable to use Attribute Routing for Web API project. It will reduce the chances of errors because in RouteConfig class there can be any mistake while creating a new custom route. Also, you don’t have to take care of the routing flow i.e, from most specific to most general. All here is the attribute you use the action method.

Roman Marusyk
  • 23,328
  • 24
  • 73
  • 116
  • Let me know if it fix the error: "The requested resource does not support http method 'GET'." – Roman Marusyk Jun 03 '20 at 19:41
  • For the most part, the Get methods are working, but I am still trying to figure out why the Posts are not. I am going to publish to a test site tonight with ssl and the whole to see what happens. Could it also be an issue with CORS? I dont think I have CORS explicitly set in this project. – Ryan Jun 03 '20 at 23:22