可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a Web API project and I am unable to enable "PUT/Patch" requests against it.
The response I get from fiddler is:
HTTP/1.1 405 Method Not Allowed
Cache-Control: no-cache
Pragma: no-cache
Allow: GET,POST,DELETE
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcUHJvamVjdHNcZG90TmV0XFdlYkFQSVxBZFNlcnZpY2VcQWRTZXJ2aWNlXGFwaVxpbXByZXNzaW9uXDE1?=
X-Powered-By: ASP.NET
Date: Tue, 06 May 2014 14:10:35 GMT
Content-Length: 72
{"message":"The requested resource does not support http method 'PUT'."}
Based on the above response, "PUT" verbs are not accepted. However, I'm unable to figure out where the related handler is configured.
The "Put" method of class is declared as follows:
[HttpPatch]
[HttpPut]
public HttpResponseMessage Put(Int32 aID, [FromBody] ImpressionModel impressionModel)
{
bla, bla, bla, bla
}
I have read and implemented the changes explained in the following threads:
- Asp.NET Web API - 405 - HTTP verb used to access this page is not allowed - how to set handler mappings
- http://www.asp.net/web-api/overview/testing-and-debugging/troubleshooting-http-405-errors-after-publishing-web-api-applications
Nothing has worked as I'm still getting a 405 response when trying to issue a "PUT" command against my Web API project.
I even commented out all of the "Handlers" in the ApplicationsHost.config file.
Working with VS2012 Premium and IIS Express (I'm assuming it's version 8). I also tried the VS Dev Server but that gave me the same result also.
I'm out of ideas. Any help would be appreciated.
Thanks Lee
回答1:
Are you using attribute routing?
This mystic error was a route attributes issue. This is enabled in your WebAPIConfig as:
config.MapHttpAttributeRoutes();
It turns out Web Api Controllers "cannot host a mixture of verb-based action methods and traditional action name routing. "; https://aspnetwebstack.codeplex.com/workitem/184
in a nutshell: I needed to mark all of my actions in my API Controller with the [Route] attribute, otherwise the action is "hidden" (405'd) when trying to locate it through traditional routing.
API Controller:
[RoutePrefix("api/quotes")]
public class QuotesController : ApiController
{
...
// POST api/Quote
[ResponseType(typeof(Quote))]
[Route]
public IHttpActionResult PostQuote(Quote quote)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Quotes.Add(quote);
db.SaveChanges();
return CreatedAtRoute("", new { id = quote.QuoteId }, quote);
}
note: my Route is unnamed so the CreatedAtRoute() name is just an empty string.
WebApiConfig.cs:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
hope this helps
回答2:
I had the exact same problem as you, and I tried all the things you tried but sometimes the solution is so trivial and under your nose, that you just don't expect it and keep looking for more complicated reasons. Make sure that in the url you're calling to test your web methods, the param names match the names in your controller method declaration. My 405 problem was solved by simply doing this (I was using query params):
My clientsController:
...
[HttpPut]
public string PutClient(string username = "", string phone= ""){...}
On my WebApiConfig:
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}"
);
And the path used to test the method must be like so: (use Postman or similar, to apply the correct web method)
http://localhost:49216/api/clients?username=Kurt&phone=443332211
Otherwise, you'll get a 405 for that http method in that controller. I didn't need to change the web.config at all (no need to remove webdav, etc..). Check this for source in the documentation:
For example, consider the following action:
public void Get(int id)
The id parameter binds to the URI. Therefore,
this action can only match a URI that contains a value for "id",
either in the route dictionary or in the query string.
Optional parameters are an exception, because they are optional. For
an optional parameter, it's OK if the binding can't get the value from
the URI.
回答3:
This happened to me when I changed the first parameter name of the PUT method
public void Put(int code, [FromBody]Lead lead)
It should be:
public void Put(int id, [FromBody]Lead lead)
And this is how it gets called:
$.ajax({
type: "PUT",
data: json,
url: "../api/leadsapi/123",
contentType: "application/json; charset=utf-8"
});
回答4:
This is also the error message returned if you forget to make the Put() method on your API controller public. Which is obvious in hindsight, but caused me a good ten minutes of head-scratching.
回答5:
had the same problem, i needed to do 3 things to solve this:
- disable Webdav in
<modules>
and <handlers>
- Make sure that HttpPut is from System.Web.Http and not from System.Web.Mvc when using WebAPI
- enable ExtensionlessUrlHandler like this
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
Hope this can help some of you to solve this nasty issue...
回答6:
This answer fixed the issue for me. I had to add the Route attribute and the problem was solved.
[HttpPut]
[Route("")]
public HttpResponseMessage MyMethod()
回答7:
You should configure it in your webservers config. It depends on the type of the webserver, where your can do it. For example by IIS, you can use a web.config file to do that in your document root. By cross-origin requests you have to add CORS headers to the response, to allow origins, methods, etc...
note: Probably you can do something about this with the ASP.NET framework as well, but I think it's unlike.
回答8:
Add the following section under Handler section in web.config:
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,POST,PUT,PATCH,MERGE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
For instance:
<handlers>
<remove name="WebDAV" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,POST,PUT,PATCH,MERGE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
回答9:
Maybe it's late now, but someone can use this.
I wanted to use PUT request and I just sent stringified object to web api and in put method only accepted that object.
JQUERY
let musterija = {
Name: name,
Email: email,
Password: password,
Username: logUser.Username,
Lastname: lastname,
GenderString: gender,
Jmbg: identification,
PhoneNumber: phone,
};
$.ajax({
method: "PUT",
url: "/api/Musterija",
data: JSON.stringify(musterija),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function () {
alert("Entity updated");
EmptyAllInputs();
$('#divprofile').show();
$('#divupdate').hide();
},
error: function (msg) {
alert("Fail - " + msg.responseText);
}
});
WEB API
[HttpPut]
public HttpResponseMessage PutMusterija(Musterija m)