Este error es muy común, probé todas las soluciones y ninguna funcionó. He desactivado la publicación de WebDAV en el panel de control y agregué esto a mi archivo de configuración web:
<handlers>
<remove name="WebDAV"/>
</handlers>
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule"/>
</modules>
El error aún persiste. Este es el controlador:
static readonly IProductRepository repository = new ProductRepository();
public Product Put(Product p)
{
return repository.Add(p);
}
Implementación del método:
public Product Add(Product item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
item.Id = _nextId++;
products.Add(item);
return item;
}
Y aquí es donde se lanza la excepción:
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
¿Alguna sugerencia?
c#
asp.net-web-api
webdav
Xardas
fuente
fuente
Tuve la misma excepción. Mi problema era que había usado:
using System.Web.Mvc; // Wrong namespace for HttpGet attribute !!!!!!!!! [HttpGet] public string Blah() { return "blah"; }
DEBIERA SER
using System.Web.Http; // Correct namespace for HttpGet attribute !!!!!!!!! [HttpGet] public string Blah() { return "blah"; }
fuente
Intenté muchas cosas para que el método DELETE funcionara (obtenía el método 405 no permitido web api), y finalmente agregué [Route ("api / scan / {id}")] a mi controlador y funcionó bien. Espero que esta publicación ayude a alguien.
// 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); }
fuente
Mi problema resultó ser el enrutamiento de atributos en WebAPI. Creé una ruta personalizada y la trató como un GET en lugar de WebAPI descubriendo que era un POST
[Route("")] [HttpPost] //I added this attribute explicitly, and it worked public void Post(ProductModel data) { ... }
Sabía que tenía que ser algo tonto (que consume todo tu día)
fuente
Chrome muchas veces intenta hacer una
OPTIONS
llamada antes de hacer una publicación. Hace esto para asegurarse de que los encabezados CORS estén en orden. Puede ser problemático si no está manejando laOPTIONS
llamada en su controlador API.public void Options() { }
fuente
Este error también puede ocurrir cuando intenta conectarse a http mientras el servidor está en https.
Fue un poco confuso porque mis solicitudes de obtención estaban bien, el problema solo estaba presente con las solicitudes posteriores.
fuente
Estaba obteniendo el 405 en mi llamada GET y el problema resultó que nombré el parámetro en el método del lado del servidor GET
Get(int formId)
y necesitaba cambiar la ruta o cambiarle el nombreGet(int id)
.fuente
También puede obtener el error 405 si dice que su método espera un parámetro y no lo está pasando.
Esto NO funciona (error 405)
Vista HTML / Javascript
$.ajax({ url: '/api/News', //.....
API web:
public HttpResponseMessage GetNews(int id)
Por lo tanto, si la firma del método es como la anterior, debe hacer:
Vista HTML / Javascript
$.ajax({ url: '/api/News/5', //.....
fuente
Llego tarde a esta fiesta, pero como nada de lo anterior era viable o funcionaba en la mayoría de los casos, así es como esto finalmente se resolvió para mí.
En el servidor en el que estaba alojado el sitio / servicio, se requería una función. ACTIVACIÓN HTTP !!!
¡Esto funcionó al instante! Que estaba derritiendo mi cerebro
fuente
Si tienes una ruta como
[Route("nuclearreactors/{reactorId}")]
Debe usar exactamente el mismo nombre de parámetro en el método, por ejemplo
public ReactorModel GetReactor(reactorId) { ... }
Si no pasa exactamente el mismo parámetro, puede obtener el error "405 método no permitido" porque la ruta no coincidirá con la solicitud y WebApi activará un método de controlador diferente con un método HTTP permitido diferente.
fuente
Aquí hay una solución
<handlers accessPolicy="Read, Script"> <remove name="WebDAV" /> </handlers>
docs.microsoft.com artículo sobre la solución
y eliminar WebDAV de los módulos
<remove name="WebDAVModule" />
fuente
Esto no responde a su pregunta específica, pero cuando tuve el mismo problema terminé aquí y pensé que más personas podrían hacer lo mismo.
El problema que tuve fue que había declarado indebidamente mi método Get como estático . Me perdí esto toda una mañana y no provocó advertencias de atributos o similares.
Incorrecto:
public class EchoController : ApiController { public static string Get() { return string.Empty; } }
Correcto:
public class EchoController : ApiController { public string Get() { return string.Empty; } }
fuente
¡[HttpPost] es innecesario!
[Route("")] public void Post(ProductModel data) { ... }
fuente
NO pude resolver esto. Tenía CORS habilitado y funcionando siempre que el POST devolviera vacío (ASP.NET 4.0 - WEBAPI 1). Cuando intenté devolver un HttpResponseMessage, comencé a recibir la respuesta HTTP 405.
Según la respuesta de Llad anterior, eché un vistazo a mis propias referencias.
Tenía el atributo [System.Web.Mvc.HttpPost] en la lista sobre mi método POST.
Cambié esto para usar:
[System.Web.Http.HttpPostAttribute] [HttpOptions] public HttpResponseMessage Post(object json) { ... return new HttpResponseMessage { StatusCode = HttpStatusCode.OK }; }
Esto solucionó mis problemas. Espero que esto ayude a alguien más.
En aras de la integridad, tenía lo siguiente en mi 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>
fuente
json
es probablenull
que las solicitudes previas al vuelo generalmente no tengan cargas útiles, o ejecutará la acción posterior dos veces.Tuvimos un problema similar. Estábamos tratando de OBTENER de:
[RoutePrefix("api/car")] public class CarController: ApiController{ [HTTPGet] [Route("")] public virtual async Task<ActionResult> GetAll(){ } }
Entonces lo haríamos
.GET("/api/car")
y esto arrojaría un405 error
.La solución:
El
CarController.cs
archivo estaba en el directorio,/api/car
por lo que cuando solicitábamos este punto final de la API, IIS enviaba un error porque parecía que estábamos tratando de acceder a un directorio virtual al que no teníamos permiso.Opción 1: cambiar / renombrar el directorio en el que se encuentra el controlador.
Opción 2: cambiar el prefijo de ruta a algo que no coincida con el directorio virtual.
fuente
En mi caso, tenía una carpeta física en el proyecto con el mismo nombre que la ruta WebAPI (por ejemplo, sandbox) y solo la solicitud POST fue interceptada por el controlador de archivos estáticos en IIS (obviamente).
Obtener un error 405 engañoso en lugar del 404 más esperado fue la razón por la que tardé mucho en solucionar el problema.
No es fácil caer en esto, pero es posible. Espero que ayude a alguien.
fuente
Por mi parte, mi controlador POST era de esta forma:
[HttpPost("{routeParam}")] public async Task<ActionResult> PostActuality ([FromRoute] int routeParam, [FromBody] PostData data)
Descubrí que tenía que intercambiar los argumentos , es decir, los datos del cuerpo primero y luego el parámetro de ruta, como este:
[HttpPost("{routeParam}")] public async Task<ActionResult> PostActuality ([FromBody] PostData data, [FromRoute] int routeParam)
fuente
revise el archivo .csproj de su proyecto y cambie
<IISUrl>http://localhost:PORT/</IISUrl>
a la URL de su sitio web como esta
<IISUrl>http://example.com:applicationName/</IISUrl>
fuente
Otro posible problema que causa el mismo comportamiento son los parámetros predeterminados en el enrutamiento. En mi caso, el controlador se ubicó y se instanciaron correctamente, pero la POST se bloqueó debido a la
Get
acción predeterminada especificada:config.Routes.MapHttpRoute( name: "GetAllRoute", routeTemplate: "api/{controller}.{ext}"/*, defaults: new { action = "Get" }*/ // this was causing the issue );
fuente
Estaba teniendo exactamente el mismo problema. Busqué durante dos horas lo que estaba mal sin suerte hasta que me di cuenta de que mi
POST
método era enprivate
lugar depublic
.Es curioso ver que el mensaje de error es algo genérico. ¡Espero eso ayude!
fuente
Asegúrese de que su controlador herede de la
Controller
clase.Incluso podría ser más loco que las cosas funcionen localmente incluso sin eso.
fuente