相关文章推荐
稳重的移动电源  ·  XML Files: WS-I, ...·  10 月前    · 
痴情的领结  ·  Business ...·  1 年前    · 
神勇威武的豆浆  ·  java - Hitting space ...·  1 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

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?

Error 'HttpClient' does not contain a definition for 'PostAsJsonAsync' is thrown, when tried your code. – agileDev Jul 6, 2020 at 7:29

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";

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)

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);
                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, 2016 at 11:52

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() { }

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

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',
         //.....
                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, 2015 at 5:49

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.

@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, 2017 at 13:11

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;

Old question but none of the answers worked for me.

This article solved my problem by adding the following lines to web.config:

<system.webServer>
  <modules runAllManagedModulesForAllRequests="false">
    <remove name="WebDAVModule" />
  </modules>
</system.webServer>
                Similar to what @Danushka suggests, I had to also put this in <handlers>  So, in addition to the above, add:   <remove name="WebDAV" /> in the handlers
– bkwdesign
                Oct 15, 2021 at 19:44
                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, 2015 at 5:37

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, 2018 at 20:25

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.

[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

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!

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.

In my case, the 405 error only showed up in production server, and not on my dev machine.

I found that the problem was due to the fact that I simply "manually" transferred the contents of the locally published folder from my local machine to the online production server.

So, the FIX for me was to simply delete all the online files on the prod server, and then use the "Publish" option on Visual Studio to publish directly from my local machine to the prod server via FTP.

I don't know exactly why this changed something, because it seems to me the files were the same, but this thing fixed the problem and I hope it could help someone else too.

Another possible cause can be to do with Session State config in IIS causing a redirect which appends "?AspxAutoDetectCookieSupport=1" to the URL. In my case I was performing a POST but the redirect was being performed as a GET by the HttpClient.

The solution I found was to add the following to my web.config:

<system.web>
   <sessionState cookieless="UseCookies" />
</system.web>

Function names make it complicated for c# sometimes. Change name of the function, it will works. Like ProductPut instead of PutProduct or Put.

public Product ProductPut(Product p)
    return repository.Add(p);
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.