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 Al
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
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>
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"
});
had the same problem, i needed to do 3 things to solve this:
<modules>
and <handlers>
<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...
This answer fixed the issue for me. I had to add the Route attribute and the problem was solved.
[HttpPut]
[Route("")]
public HttpResponseMessage MyMethod()
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.