9

I Created a simple web api service to GET & POST User Data.

Every thing is well at Localhost. But when i host Service at server, Get Method is working fine when i call it from PostMan/Browser. But Post Methods always returns "The requested resource does not support http method 'GET'." Status: 405 Method Not Allowed.

One thing i got Confused here i.e I requested a POST Call, but status message shows me 'GET' error. Why it should be? If it is CORS problem? I tried CORS enable too with various scenarios/aspects by searching answers on internet at Application level(Web.Config as well Nuget Package Manager Cors). Still getting 405 Method Not Allowed. Below pasted my API Code:

Controller NameSpaces:

  using MySql.Data.MySqlClient;
  using System;
  using System.Collections.Generic;
  using System.Data;
  using System.Linq;
  using System.Net;
  using System.Net.Http;
  using System.Web.Http;
  using System.Web.Http.Cors;

Controller

  public class UsersController : ApiController
  {
    [Route("api/Users/GetUsers/{UserId}")]
    [HttpGet]
    public IEnumerable<User> GetUsers(int UserId)
    {
        try
        {
            List<User> userlist = new List<User>();
            MySqlCommand cmd = new MySqlCommand("GetUsers");
            cmd.Parameters.AddWithValue("aUserId", UserId);
            cmd.CommandType = CommandType.StoredProcedure;
            DataTable dt = obj.GetData(out ErrorMsg, cmd);
            // Did Some Stuff and Returns Model;
            return userlist;
        }
        catch(Exception ex)
        {
            // Written Error Log & Returns Empty Model;
        }
    }

    [Route("api/Users/SaveUser")]
    [HttpPost]
    public IEnumerable<User> SaveUser([FromBody]dynamic request)
    {
        try
        {
            string UserName = request.Param_Name;
            string Email = request.Param_Email;
            List<User> userlist = new List<User>();
            MySqlCommand cmd = new MySqlCommand("UserSave");
            cmd.Parameters.AddWithValue("aUserName", UserName);
            cmd.Parameters.AddWithValue("aEmail", Email);
            cmd.CommandType = CommandType.StoredProcedure;
            DataTable dt = obj.GetData(out ErrorMsg, cmd);
            UserAuthenticate userdata;
            // Did Some Stuff and returns UserModel;
            return userlist;
        }
        catch(Exception Ex)
        {
            // Written Error Log & Returns Empty Model with Error Message;
        }
    }

    [Route("api/Users/SaveUserModel")]
    [HttpPost]
    public IEnumerable<User> SaveUserModel([FromBody]User request)
    {
        try
        {
            string Param_UserName = request._UserName;
            string Param_Email = request._Email;
            List<User> userlist = new List<User>();
            MySqlCommand cmd = new MySqlCommand("UserSave");
            cmd.Parameters.AddWithValue("aUserName", Param_UserName);
            cmd.Parameters.AddWithValue("aEmail", Param_Email );
            cmd.CommandType = CommandType.StoredProcedure;
            DataTable dt = obj.GetData(out ErrorMsg, cmd);
            UserAuthenticate userdata;
            // Did Some Stuff and returns UserModel;
            return userlist;
        }
        catch(Exception Ex)
        {
            // Written Error Log & Returns Empty Model with Error Message;
        }
    }
 }

Model

public class User
{
    public int _UserID { get; set; }
    public string _Email { get; set; }
    public string _UserName { get; set; }
}

Web.Config

Web.Config File Pasted here in Image

WebApi.Config

Namespaces

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Web.Http;
using System.Web.Http.Cors;

WebApiConfig Class

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        var cors = new EnableCorsAttribute("*", "*", "*");
        config.EnableCors(cors);
        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
    }
}

PostMan Request & Response

Headers for Above PostMan Request

Access-Control-Allow-Methods →*
Access-Control-Allow-Origin →*
Access-Control-Request-Headers →: *
Access-Control-Request-Method →: *
Allow →POST
Cache-Control →no-cache
Content-Length →72
Content-Type →application/json; charset=utf-8
Date →Wed, 16 Nov 2016 17:50:03 GMT
Expires →-1
Pragma →no-cache
Server →Microsoft-IIS/7.5
X-AspNet-Version →4.0.30319

Thanks for any Helps!! Got Wasted a Day for this error.

Anil Kumar
  • 91
  • 1
  • 1
  • 4
  • 1
    how are you calling this API? and which method? – Vivek Nuna Nov 16 '16 at 19:08
  • Through Post Man I'm calling. Method is SaveUser & SaveUserModel. Attached PostMan Request & Response Image. As Well Pasted Headers – Anil Kumar Nov 16 '16 at 19:11
  • Are you sure? you are selecting POST? – Vivek Nuna Nov 16 '16 at 19:14
  • @viveknuna Yeah! i'm sure – Anil Kumar Nov 16 '16 at 19:15
  • and what url are u hitting ? – Vivek Nuna Nov 16 '16 at 19:16
  • @viveknuna have a look at https://i.stack.imgur.com/zrlMC.png – Anil Kumar Nov 16 '16 at 19:17
  • http://url.com/api/Users/SaveUser url.com is dummy domain which i gave to understand u the problem. – Anil Kumar Nov 16 '16 at 19:20
  • _UserID=abc&_Email =xyz&_UserName=pqr You have to make sure that the HTTP header contains Content-Type: application/x-www-form-urlencoded Call SaveUser with these things, surely it will work – Vivek Nuna Nov 16 '16 at 19:24
  • Did it solve your problem ? – Vivek Nuna Nov 16 '16 at 19:35
  • @viveknuna I tried as you suggested and below are the header POST /api/Users/SaveUser HTTP/1.1 Host: XXXXX Content-Type: application/x-www-form-urlencoded Cache-Control: no-cache Postman-Token: ef327cf8-a300-6528-0157-accced4ee3b9 Param_Name=120&Param_Email=MyName but still not solved – Anil Kumar Nov 16 '16 at 19:36
  • then what happened ? – Vivek Nuna Nov 16 '16 at 19:37
  • Same error Message with 405 Status – Anil Kumar Nov 16 '16 at 19:38
  • I'm sorry, you have to call SaveUserModel with these parameters. then We will try to solve for SaveUser – Vivek Nuna Nov 16 '16 at 19:39
  • I tried with SaveUserModel with same parameters, still getting same error – Anil Kumar Nov 16 '16 at 19:41
  • You class variable isUserName or _UserName – Vivek Nuna Nov 16 '16 at 19:42
  • In model i'm having _UserName, i already got compilation error at SaveUserModel method coz of i'm given UserName. Changed to _UserName. Still problem exist – Anil Kumar Nov 16 '16 at 19:45
  • First fix that problem . try to keep the member name same across application and pass the same name in Post request – Vivek Nuna Nov 16 '16 at 19:46
  • Already Fixed, and tried SaveUserModel post call again. Error as it is 405 – Anil Kumar Nov 16 '16 at 19:51
  • That user input model, there's no requirement to have 'param_' in the body of your request in Postman. The model binding will match the model if you specify the object correctly. just use the Json notation. I would suggest commenting out all other api calls for that controller... just to see if its another Route that is conflicting.. if it starts working, uncomment one at a time to see where the issue lies. – Derek Nov 17 '16 at 12:37
  • why are you using dynamic objects in the requests? – Derek Nov 17 '16 at 12:42
  • @Derek Hi, FYI. Yes at earlier stage of api development, i developed api with only model which is working fine at local level. when i moved api to server level its getting 405 error. so, i preferred alternate api with dynamic objects which dynamic objects also supports API post calls with 4.5 framework. – Anil Kumar Nov 17 '16 at 17:35
  • as well no other controller nor route is there among solution (as of my knowledge i think if another route conflicts happen it won't return 405 error). – Anil Kumar Nov 17 '16 at 17:39
  • Hi, did you solve your problem? I'm having the same issue and currently have no ideas on what's wrong... – Prokurors Nov 25 '16 at 12:41
  • At last, Problem Solved. Its Because of something missed in requested url. i.e "www". To Make Post call success, we need to append www in url like below "http: //www.url.com/api/User/SaveUser". But, i'm always trying without www which always get 405 Error – Anil Kumar Nov 30 '16 at 17:04
  • @Prokurors Problem is solved, Just Add, WWW in URL at post calls. Then your problem will resolved. – Anil Kumar Nov 30 '16 at 17:12

3 Answers3

18

I know this is an old post but, for anyone else looking for a solution to this problem. I had this issue and realized that I was posting to my webapi using http but IIS was redirecting my request to https. This redirect was causing postman to change the POST to a GET. changing my URL to https fixed the problem for me.

Gregg Duncan
  • 2,635
  • 1
  • 14
  • 20
2

here is the solution of your problem

ASP.NET WebApi : (405) Method Not Allowed

Finally I changed the cookieless="AutoDetect" in web.config to cookieless="UseCookies" and the problem solved.

Community
  • 1
  • 1
0

If you have not Enabled CORS decorate your controller as below.

  [EnableCors(origins: "*", headers: "*", methods: "GET, POST, PUT, DELETE")] 

Also put belo code in webapiconfig.cs file

  config.EnableCors();

If you are hosting your endpoints in public api then decorate controller as below.

 [RoutePrefix("api/users")]
    public class usersController : ApiController

Then Get for example,

   //Get http:192.168.0.0:2210/api/users/
      [Route("~/api/users")]

     //POST  http:192.168.0.0:2210/api/users/
     [Route("~/api/users")] 

    //Get on id
     //POST  http:192.168.0.0:2210/api/users/
     [Route("~/api/users/{id}")] 
Niranjan Godbole
  • 2,135
  • 7
  • 43
  • 90