32

In my web api controller i have a function with following codes

       [HttpPost]
        public HttpResponseMessage Post(string schooltypeName)
        {
            _schoolTypeService.RegisterSchoolType(schooltypeName);

            var message = Request.CreateResponse(HttpStatusCode.Created);

            return message;
        }

When i am calling with fiddler i am getting this error

{"Message":"The requested resource does not support http method 'POST'."}

my fiddling parameters are

Header

User-Agent: Fiddler

Host: myhost:8823

Content-Type: application/json; charset=utf-8

Content-Length: 26

Request body

{"schooltypeName":"Aided"}

Requesting url are

http://myhost:8823/SchoolType

( i configured url ,GET is working with this url)

Whats wrong here ?

Bug
  • 2,576
  • 2
  • 21
  • 36
Binson Eldhose
  • 417
  • 2
  • 6
  • 9

7 Answers7

53

Change your action to be like Post([FromBody]string schooltypeName) as by default string type is expected to come Uri.

Updated:
Change your body to just "Aided" as currently you would need a class to make the deserialiation work otherwise (ex:class School { public string SchoolTypeName { get; set; } }

Kiran
  • 56,921
  • 15
  • 176
  • 161
  • 1
    changed but i am always getting null value as parameter – Binson Eldhose Feb 01 '14 at 06:38
  • 4
    Your comment, "by default string type is expected to come Uri", comes as news to me. I've been using Web API for years but I guess have always used classes in params. I was pulling my hair out all morning over this... wish it were more publicized. – Jay Querido May 29 '14 at 18:40
17

See the using namespace at the top of the controller, if you're using System.Web.Mvc, then this problem might be occurred:

Use this:

using System.Web.Http;
Sohail xIN3N
  • 2,951
  • 2
  • 30
  • 29
  • This is actually ultimately unnecessary, because you also have to decorate the call. In that decoration, you have to specify the namespace or it will automatically default to `[System.Web.Mvc.HttpPost]` instead of the correct version for a class inheriting from `WebApiController`, which is `[System.Web.Http.HttpPost]`, if you don't have the `using` statement; and if you do have the `using`, it will enforce making you put the whole thing, anyway, because it conflicts. – vapcguy Apr 06 '18 at 01:09
10

The Problem comes down to this:

if your routes in startup is registered with routes.MapRoute( you must decorate your post methods with [System.Web.Mvc.HttpPost]

If your routes in startup is registered with Routes.MapHttpRoute( you must decorate your post methods with [System.Web.Http.HttpPost]

if you use MapRoute() with [System.Web.Http.HttpPost] it wont work

if you use MapHttpRoute() with [System.Web.Mvc.HttpPost] it wont work

Gerrie Pretorius
  • 3,381
  • 2
  • 31
  • 34
7

For future readers. I found this question..but found (my) answer elsewhere.

I decorated the method with the attribute seen below.

    [System.Web.Http.HttpPost]
    public MyOutputObject DoSomething([FromBody]MyInputObject args)
    {
        Console.Writeline(args.ToString());
        return new MyOutputObject();
    }

My client code (C#, console app) for completeness. Please note it is NOT an good example of async/await since it has .Result in it.

    private static Task<MyOutputObject> MyClientCall(string baseAddress, MyInputObject args)
    {
        HttpClient client = new HttpClient();
        client.BaseAddress = new Uri(baseAddress);
        client.DefaultRequestHeaders.Accept.Add(
           new MediaTypeWithQualityHeaderValue("application/json"));

           /* Your class name would be "MyEntityController" most likely */
        string serviceUrl = baseAddress + @"api/MyEntity/DoSomething";

        HttpResponseMessage response = client.PostAsJsonAsync(serviceUrl, args).Result;

        Console.WriteLine(response);
        Console.WriteLine(response.Content.ReadAsStringAsync().Result);

        if (!response.IsSuccessStatusCode)
        {
            Console.WriteLine("ERROR:  :(   " + response.ReasonPhrase);
            return null;
        }
        Task<MyOutputObject> wrap = response.Content.ReadAsAsync<MyOutputObject>();
        return wrap;
    }

I found my answer here:

http://blog.dontpaniclabs.com/post/2013/01/23/That-Pesky-Requested-Resource-Does-Not-Support-HTTP-Method-POST-Error-When-Using-MVC-Web-API

granadaCoder
  • 26,328
  • 10
  • 113
  • 146
  • 1
    Long story short, then, you had `[HttpPost]` instead of `[System.Web.Http.HttpPost]`. Same as the other responses that didn't address the real issue, that he needed `[FromBody]` in the `Post` call. It's worth noting, but it ultimately wasn't the only problem. – vapcguy Apr 06 '18 at 01:04
3

Please Check your GET Action method name you are using. Chances are you might be using the same Route names to GET method and POST method and expecting the result.

Example :

Controller name : StudentController

    [Route("api/Student/names")]
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] { "student1", "student2" };
    }

Url for method (GET): http://localhost:59342/api/student/names

     [HttpPost]
     [Route("api/Student/names")]
     public String Post(String name)
     {
         return "success";
     }

For POST method to url : http://localhost:59342/api/student/names

Then you will get the above mentioned error

Solution: Change the POST action method name like below

    [HttpPost]
    [Route("api/Student/getName")]
    public String Post(String name)
    {
        return "success";
    }

Then url which is used to get the response for post method is :

http://localhost:59342/api/student/getName

Thriveni
  • 742
  • 9
  • 11
2

What helped to me at the end was adding the Route attribute, and just repeating there the same route which as registered globally.

Đonny
  • 910
  • 10
  • 11
0

If you add attribute [RoutePrefix("samplePrefix")] for controller class, but not add attribute [Route("sampleRoute")] for specified post method, this issue may occurs.