可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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?
回答1:
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);
回答2:
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";
}
回答3:
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);
}
回答4:
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)
回答5:
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)
.
回答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() { }
回答7:
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',
//.....
回答8:
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.
回答9:
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" />
回答10:
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
回答11:
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.
回答12:
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;
}
}
回答13:
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>
回答14:
[HttpPost] is unnecessary!
[Route("")]
public void Post(ProductModel data)
{
...
}
回答15:
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>
回答16:
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
);
回答17:
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!
回答18:
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.