C#-WebApi-405 method not allowed Web API

405 method not allowed Web API

This error is very common, and I tried all of the solutions and non of them worked. I have disabled WebDAV publishing in control panel and added this to my web config file:

  <handlers>
  <remove name="WebDAV"/>
  </handlers>
  <modules runAllManagedModulesForAllRequests="true">
  <remove name="WebDAVModule"/>
  </modules>

The error still persists. This is the controller:

   static readonly IProductRepository repository = new ProductRepository();

    public Product Put(Product p)
    {
        return repository.Add(p);
    }

Method implementation:

 public Product Add(Product item)
    {
        if (item == null)
        {
            throw new ArgumentNullException("item");
        }
        item.Id = _nextId++;
        products.Add(item);
        return item;
    }

And this is where the exception is thrown:

client.BaseAddress = new Uri("http://localhost:5106/");
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));      
var response = await client.PostAsJsonAsync("api/products", product);//405 exception

Any suggestions?

c# asp.net-web-api webdav

shareeditfollow

edited Nov 28 '19 at 11:04

 

Luke Girvin

12.3k88 gold badges5353 silver badges7575 bronze badges

asked Mar 30 '13 at 12:53

 

Xardas

1,35744 gold badges1616 silver badges2929 bronze badges

add a comment

21 Answers

ActiveOldestVotes

59

 

You are POSTing from the client:

await client.PostAsJsonAsync("api/products", product);

not PUTing.

Your Web API method accepts only PUT requests.

So:

await client.PutAsJsonAsync("api/products", product);

shareeditfollow

answered Mar 30 '13 at 12:58

Darin Dimitrov

911k239239 gold badges31233123 silver badges28262826 bronze badges

add a comment

59

 

I had the same exception. My problem was that I had used:

using System.Web.Mvc; // Wrong namespace for HttpGet attribute !!!!!!!!!
[HttpGet]
public string Blah()
{
    return "blah";
}

SHOULD BE

using System.Web.Http; // Correct namespace for HttpGet attribute !!!!!!!!!
[HttpGet]
public string Blah()
{
    return "blah";
}

shareeditfollow

edited May 8 '14 at 7:33

 

Beatles1692

4,5802525 silver badges5858 bronze badges

answered Feb 24 '14 at 21:20

 

Llad

59944 silver badges33 bronze badges

add a comment

18

 

I tried many thing to get DELETE method work (I was getting 405 method not allowed web api) , and finally I added [Route("api/scan/{id}")] to my controller and was work fine. hope this post help some one.

     // DELETE api/Scan/5
    [Route("api/scan/{id}")]
    [ResponseType(typeof(Scan))]
    public IHttpActionResult DeleteScan(int id)
    {
        Scan scan = db.Scans.Find(id);
        if (scan == null)
        {
            return NotFound();
        }

        db.Scans.Remove(scan);
        db.SaveChanges();

        return Ok(scan);
    }

shareeditfollow

answered Sep 3 '14 at 3:14

 

user2662006

1,8501616 silver badges1515 bronze badges

  • For some reason my it was only not working for the delete, for creating and updating it worked fine. Well, I just added [HttpPost] and it worked. But thanks, you got me on the right track and only cost me 5 mins now :) – Rubenisme Jul 15 '16 at 11:52

  • 1

    Why aren't you just adding the [HttpDelete] attribute? – johnny 5 Dec 11 '17 at 22:03

add a comment

12

 

My problem turned out to be Attribute Routing in WebAPI. I created a custom route, and it treated it like a GET instead of WebAPI discovering it was a POST

    [Route("")]
    [HttpPost] //I added this attribute explicitly, and it worked
    public void Post(ProductModel data)
    {
        ...
    }

I knew it had to be something silly (that consumes your entire day)

shareeditfollow

answered Aug 14 '14 at 15:39

 

Nexxas

74311 gold badge77 silver badges1313 bronze badges

add a comment

6

 

Chrome often times tries to do an OPTIONS call before doing a post. It does this to make sure the CORS headers are in order. It can be problematic if you are not handling the OPTIONS call in your API controller.

public void Options() { }

shareeditfollow

answered Jul 3 '15 at 20:48

Nate Zaugg

3,87922 gold badges3333 silver badges4949 bronze badges

add a comment

6

 

This error can also occur when you try to connect to http while the server is on https.

It was a bit confusing because my get-requests were OK, the problem was only present with post-requests.

shareeditfollow

edited Feb 6 '18 at 10:24

answered Feb 6 '18 at 10:19

 

FrankyHollywood

1,0211111 silver badges1414 bronze badges

  • Thanks for your explanation, It worked for me :) – Braytiner Aug 22 '19 at 12:10

add a comment

4

 

You can also get the 405 error if say your method is expecting a parameter and you are not passing it.

This does NOT work ( 405 error)

HTML View/Javascript

$.ajax({
         url: '/api/News',
         //.....

Web Api:

public HttpResponseMessage GetNews(int id)

Thus if the method signature is like the above then you must do:

HTML View/Javascript

$.ajax({
         url: '/api/News/5',
         //.....

shareeditfollow

answered Sep 3 '15 at 20:37

 

Tom Stickel

15.8k66 gold badges9696 silver badges105105 bronze badges

  • I seem to be running into 405 errors for various reasons, they do all boil down to the fact of it attempting to HIT the method signature and a parameter issue or a convention naming issue or a Attribute issue etc... – Tom Stickel Sep 17 '15 at 5:49

add a comment

4

 

If you have a route like

[Route("nuclearreactors/{reactorId}")]

You need to use the exact same parameter name in the method e.g.

public ReactorModel GetReactor(reactorId)
{
 ...
}

If you do not pass the exact same parameter you may get the error "405 method not allowed" because the route will not match the request and WebApi will hit a different controller method with different allowed HTTP method.

shareeditfollow

edited Apr 1 '17 at 13:14

answered Apr 1 '17 at 10:42

roylac

7144 bronze badges

  • This is not an answer either! – Div Apr 1 '17 at 11:08

  • @Div "405 method not allowed" can be shown in the case I shared because the method will not catch api-call as the route setup is invalid. The api-call may then hit another unintended method which could have a different HTTP action allowed. Yes I agree that this answer may not be 100% relevant for the actual question, however the title of the question by Xardas is not very specific and I believe that many people landing here in search of answers to the question as stated by the title may find this answer useful. – roylac Apr 1 '17 at 13:11

 

 

Here is one solution

<handlers accessPolicy="Read, Script"> <remove name="WebDAV" /> </handlers>

docs.microsoft.com solution article

and remove WebDAV from modules

<remove name="WebDAVModule" />

 

I was getting the 405 on my GET call, and the problem turned out that I named the parameter in the GET server-side method Get(int formId), and I needed to change the route, or rename it Get(int id).

 

 

I'm late to this party but as nothing above was either viable or working in most cases, here is how this was finally resolved for me.

On the server the site/service was hosted on, a feature was required! HTTP ACTIVATION!!!

Server Manager > Manage > Add Roles and Features > next next next till you get to Features > Under .NET (each version) tick HTTP Activation. Also note there is one hidden under >net > WCF Services.

This then worked instantly! That was melting my brain

 

I could NOT solve this. I had CORS enabled and working as long as the POST returned void (ASP.NET 4.0 - WEBAPI 1). When I tried to return a HttpResponseMessage, I started getting the HTTP 405 response.

Based on Llad's response above, I took a look at my own references.

I had the attribute [System.Web.Mvc.HttpPost] listed above my POST method.

I changed this to use:

[System.Web.Http.HttpPostAttribute]
[HttpOptions]
public HttpResponseMessage Post(object json)        
{
    ...
    return new HttpResponseMessage { StatusCode = HttpStatusCode.OK };
}

This fixed my woes. I hope this helps someone else.

For the sake of completeness, I had the following in my web.config:

<httpProtocol>
    <customHeaders>
        <clear />
        <add name="Access-Control-Expose-Headers " value="WWW-Authenticate"/>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, PATCH, DELETE" />
        <add name="Access-Control-Allow-Headers" value="accept, authorization, Content-Type" />
        <remove name="X-Powered-By" />
    </customHeaders>
</httpProtocol>

 

  • This will have the method called on the OPTIONS pre-flight request (as well as on POST), at which point json is likely null since pre-flight requests usually don't have payloads, or you'll run the post action twice. – glennsl Sep 3 '18 at 20:25

 

 

This does not answer your specific question, but when I had the same problem I ended up here and I figured that more people might do the same.

The problem I had was that I had indeliberately declared my Get method as static. I missed this an entire forenoon, and it caused no warnings from attributes or similar.

Incorrect:

public class EchoController : ApiController
{
    public static string Get()
    {
        return string.Empty;
    }
}

Correct:

public class EchoController : ApiController
{
    public string Get()
    {
        return string.Empty;
    }
}

 

[HttpPost] is unnecessary!

[Route("")]
public void Post(ProductModel data)
{
    ...
}

shareeditfollow

answered Aug 21 '14 at 10:39

 

user3963793

3111 bronze badge

  • Yes the way that you are doing it is correct in that you do not need an explicit [HttpPost] , however there are some people not following convention (yikes) and thus something like [Route("MyMethodSaver"] public string MyMethodtoSave(int? id) --> that would need a [HttpPost] and it would then work – Tom Stickel Sep 17 '15 at 5:37

add a comment

1

 

We had a similar issue. We were trying to GET from:

[RoutePrefix("api/car")]
public class CarController: ApiController{

    [HTTPGet]
    [Route("")]
    public virtual async Task<ActionResult> GetAll(){

    }

}

So we would .GET("/api/car") and this would throw a 405 error.

 


The Fix:

 

The CarController.cs file was in the directory /api/car so when we were requesting this api endpoint, IIS would send back an error because it looked like we were trying to access a virtual directory that we were not allowed to.

Option 1: change / rename the directory the controller is in
Option 2: change the route prefix to something that doesn't match the virtual directory.

 

 

check in your project .csproj file and change

<IISUrl>http://localhost:PORT/</IISUrl>

to your website url like this

<IISUrl>http://example.com:applicationName/</IISUrl>

 

 

For my part my POST handler was of this form:

[HttpPost("{routeParam}")]
public async Task<ActionResult> PostActuality ([FromRoute] int routeParam, [FromBody] PostData data)

I figured out that I had to swap the arguments, that is to say the body data first then the route parameter, as this:

[HttpPost("{routeParam}")]
public async Task<ActionResult> PostActuality ([FromBody] PostData data, [FromRoute] int routeParam)

 

 

Another possible issue which causes the same behavior is the default parameters in the routing. In my case the controller was located and instantiated correctly, but the POST was blocked because of default Get action specified:

config.Routes.MapHttpRoute(
    name: "GetAllRoute",
    routeTemplate: "api/{controller}.{ext}"/*,
    defaults: new { action = "Get" }*/ // this was causing the issue
);

shareeditfollow

answered Mar 6 '17 at 20:48

 

Eadel

2,94155 gold badges3030 silver badges4141 bronze badges

add a comment

0

 

In my case I had a physical folder in the project with the same name as the WebAPI route (ex. sandbox) and only the POST request was intercepted by the static files handler in IIS (obviously).

Getting a misleading 405 error instead of the more expected 404, was the reason it took me long to troubleshoot.

Not easy to fall-into this, but possible. Hope it helps someone.

 

 

I was having exactly the same problem. I looked for two hours what was wrong with no luck until I realize my POST method was private instead of public .

Funny now seeing that error message is kind of generic. Hope it helps!

 

Make sure your controller inherits from Controller class.

It might even be crazier that stuff would work locally even without that.

HTTP 405错误通常发生在使用Ajax调用Web API时,这是因为Web API默认情况下只支持GET和POST请求,而不支持PUT、DELETE、OPTIONS等请求方法。解决这个问题的方法是在Web API端添加一个处理OPTIONS请求的方法。 在Web API中,可以使用Web API的CORS功能来解决这个问题。CORS(跨域资源共享)是一种Web标准,允许在不同域名下的浏览器访问服务器资源。 为了启用CORS,需要在Web API项目中安装Microsoft.AspNet.WebApi.Cors NuGet包。然后,在WebApiConfig类中启用CORS: ``` using System.Web.Http; using System.Web.Http.Cors; public static class WebApiConfig { public static void Register(HttpConfiguration config) { // 启用CORS var cors = new EnableCorsAttribute("*", "*", "*"); config.EnableCors(cors); // ...其他配置 } } ``` 这里的“*”表示允许任何域名、任何方法、任何标头访问Web API。你也可以指定具体的域名、方法和标头。 在客户端使用Ajax时,需要设置withCredentials为true,这样才能在跨域请求时发送Cookies和认证信息。例如: ``` $.ajax({ type: "POST", url: "http://example.com/api/resource", data: JSON.stringify({data: "hello"}), contentType: "application/json", xhrFields: { withCredentials: true }, success: function(data) { console.log(data); }, error: function(xhr, status, error) { console.log(xhr.responseText); } }); ``` 在这个例子中,我们向http://example.com/api/resource发送一个带有数据的POST请求,并设置withCredentials为true,以便发送Cookies和认证信息。如果请求成功,我们将收到响应数据,并将其打印到控制台中。如果请求失败,我们将打印xhr.responseText,这包含了服务器返回的错误信息。 希望这个解决方案可以帮助你解决问题!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值