WebAPI Delete no funciona - Método 405 no permitido

120

¡Agradezco cualquier ayuda en esto ya que se supone que el sitio estará disponible esta noche!

Tengo un controlador de API web con un método Delete. El método se ejecuta bien en mi máquina local que ejecuta IIS Express (Windows 8) pero tan pronto como lo implementé en el servidor IIS en vivo (Windows Server 2008 R2) dejó de funcionar y muestra el siguiente mensaje de error:

Error HTTP 405.0 - Método no permitido La página que está buscando no se puede mostrar porque se está utilizando un método no válido (verbo HTTP)

He buscado soluciones en la web e implementé las más razonables. Mi configuración web tiene las siguientes configuraciones:

<system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
<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" />
</handlers>
</system.webServer>

También intenté cambiar las asignaciones de controladores y el filtrado de solicitudes en IIS sin éxito. Tenga en cuenta que las reglas de creación de WebDAV en IIS parecen estar deshabilitadas.

Cualquier idea será muy apreciada Gracias.

Chris
fuente

Respuestas:

199

¡Finalmente encontré la solución! Si se encuentra con el mismo problema, agregue lo siguiente a su web.config

<system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <modules runAllManagedModulesForAllRequests="true">
        <remove name="WebDAVModule"/> <!-- ADD THIS -->
    </modules>
    ... rest of settings here

espero que esto ayude

Chris
fuente
2
También tuve que agregar una eliminación en la sección de controladores según stackoverflow.com/a/6698096/254156
rrrr
3
También trabajó aquí. Pero, ¿alguien puede explicarme la relación con WebDAVModule?
Boas Enkler
11
para aquellos que simplemente copian y pegan: runAllManagedModulesForAllRequests = "true" no es realmente necesario y puede romper otras cosas.
Zar Shardan
Algunas otras publicaciones web sugerirán eliminar el módulo usando la sección Módulos IIS, esto lo deshabilita pero aún causa este / un problema similar, este es el método más confiable
Anthony Main
4
@ZarShardan (y otros) FYI: Si elimina el atributo runAllManagedModulesForAllRequests = "true", también deberá agregar <remove name = "WebDAV" /> debajo del nodo <handlers>.
Aaron
65

En algunos casos, eliminarlo solo de los módulos puede producir el siguiente error:

500.21 El controlador "WebDAV" tiene un módulo "WebDAVModule" incorrecto en su lista de módulos

Módulo: Notificación de IIS Web Core: ExecuteRequestHandler "

Se sugirió una solución aquí . También es necesario quitarlo de los manipuladores.

<system.webServer>
    <modules>
        <remove name="WebDAVModule" />
    </modules>
    <handlers>
        <remove name="WebDAV" />
    </handlers>
</system.webServer>
aleha
fuente
1
esto funciona para mí, pero ¿alguien puede arrojar algo de luz sobre qué es WebDAV en realidad?
Nazrul Muhaimin
31

En mi caso, ninguna de las soluciones anteriores funcionó. Esto se debió a que había cambiado el nombre del parámetro en mi Deletemétodo.

yo tenía

public void Delete(string Questionid)

en vez de

public void Delete(string id)

Necesito usar el idnombre porque ese es el nombre que se declara en mi WebApiConfigarchivo. Tenga iden cuenta el nombre en la tercera y cuarta líneas:

            config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

Obtuve esta solución de aquí .

Hugo Nava Kopp
fuente
15

El DELETEverbo Javascript para HTTP debe ser así:

$.ajax({
    **url: "/api/SomeController/" + id,**
    type: "DELETE",
    dataType: "json",
    success: function(data, statusText) {
        alert(data);
    },
    error: function(request, textStatus, error) {
        alert(error);
        debugger;
    }
});

No , no usar algo como esto:

...
data: {id:id}
...

como cuando usas el POSTmétodo.

Pavel Kharibin
fuente
1
Hola @Pavel, esto es correcto si de hecho está utilizando una implementación completamente RESTful. Desafortunadamente, no todo el mundo hace esto y es bastante común que los desarrolladores utilicen POST en lugar de DELETE, etc. Gracias por aclarar esto.
Chris
5

Después de probar casi todas las soluciones aquí, esto funcionó para mí. Agregue esto en su archivo de configuración de API

<system.webServer>
    <handlers>
      <remove name="WebDAV" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
    <modules>
        <remove name="WebDAVModule" />
    </modules>
</system.webServer>
Nithin Chandran
fuente
Intenté muchas cosas, esto funcionó. .NET versión 4.6.1 - Gracias.
Ketan
4

Si está utilizando IIS 7.0 o una versión posterior. Este problema está relacionado principalmente con el módulo de extensión WebDAV en el servidor IIS. esto sucedió mientras se usaba la acción Publicar o eliminar.

Pruebe la siguiente configuración en la configuración web

<system.webServer>
   <modules>
       <remove name="WebDAVModule" />
   </modules>
   <handlers>
     <remove name="WebDAV" />
   </handlers>
</system.webServer>
Abhishek B.
fuente
3

También tuve el mismo problema, estoy llamando a WebAPi y aparece este error. Agregar la siguiente configuración en web.config para servicios resolvió mi problema

    <modules runAllManagedModulesForAllRequests="true">
        <remove name="WebDAVModule"/> <!-- add this -->
    </modules>

en el archivo web.config resolvió mi problema. Así es como estaba llamando desde el lado del cliente

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri(environment.ServiceUrl);
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    HttpResponseMessage response = client.DeleteAsync("api/Producer/" + _nopProducerId).Result;
    if (response.IsSuccessStatusCode)
    {
        string strResult = response.Content.ReadAsAsync<string>().Result;
    }
}
Aamir
fuente
2

Vaya al archivo applicationHost.config (generalmente en C: \ Windows \ System32 \ inetsrv \ config) y comente la siguiente línea en applicationHost.config

1) Debajo de <handlers>:

<add name="WebDAV" path="*" verb="PROPFIND,PROPPATCH,MKCOL,PUT,COPY,DELETE,MOVE,LOCK,UNLOCK" modules="WebDAVModule" resourceType="Unspecified" requireAccess="None" />

2) También comente el siguiente módulo al que hace referencia el controlador anterior en <modules>

<add name="WebDAVModule" />
arviman
fuente
O use la otra respuesta stackoverflow.com/a/47907578/1754743 para ELIMINAR estos controladores en su propio web.config, si no desea (o no puede) modificar el archivo de configuración de toda la máquina
Ekus
2

En mi caso, omití agregar {id}al [Route("")]y obtuve el mismo error. Agregar eso solucionó el problema para mí:[Route("{id}")]

Reza
fuente
Tantas horas de tiempo perdido, y si no fuera por ti, todavía no podría resolver esto ... Me pregunto por qué no devuelve 404: @
deadManN
1

Tuve el error 405 Método no permitido porque había omitido hacer público el método Delete en el controlador WebApi.

Me tomó mucho tiempo encontrar esto (¡demasiado tiempo!) Porque habría esperado un error No encontrado en este caso, por lo que asumí incorrectamente que mi método Eliminar estaba siendo denegado.

El motivo de No permitido en lugar de No encontrado es que también tenía un método Get para la misma ruta (que será el caso normal al implementar REST). La función pública Get coincide con el enrutamiento y luego se niega debido al método http incorrecto.

Un simple error que conozco, pero puede ahorrarle tiempo a alguien más.

Pablo D
fuente
1

Solo para agregar. Si esta es tu configuración

config.Routes.MapHttpRoute (
            nombre: "DefaultApi",
            routeTemplate: "api / {controller} / {id}",
            valores predeterminados: nuevo {id = RouteParameter.Optional}

siga haciendo lo que dijo Hugo, y no configure el atributo de ruta en el método de obtención del controlador, esto dio un problema en mi caso.

usuario6247020
fuente
0

Tuve un problema similar pero para PUT: ninguna de las otras sugerencias funcionó para mí.

Sin embargo, estaba usando en intlugar del predeterminado stringpara la identificación. agregar {id:int}a la ruta resolvió mi problema.

    [Route("api/Project/{id:int}")]
    public async Task<IHttpActionResult> Put(int id, [FromBody]EditProjectCommand value)
    {
       ...
    }
Tiene
fuente
0

Tuvimos que agregar encabezados personalizados a nuestro web.config ya que nuestra solicitud tenía varios encabezados que confundían la respuesta de la API.

<httpProtocol>
    <customHeaders>
        <remove name="Access-Control-Allow-Methods" />
        <remove name="Access-Control-Allow-Origin" />
        <remove name="Access-Control-Allow-Headers" />
    </customHeaders>
</httpProtocol>
Zadok
fuente
-1

El atributo [HttpPost] en la parte superior del método Delete resolvió este problema para mí:

[HttpPost]
public void Delete(int Id)
{
  //Delete logic
}
Andriy Gubal
fuente
Esa podría ser una de las razones por las que le está funcionando. Estaba en una versión anterior, a principios de 2013, por lo que se han arreglado bastantes cosas desde entonces. Sin embargo, me alegra saber que está funcionando para usted.
Chris
4
Esta no es una buena respuesta para ser honesto. Las personas cuyo problema se resolvió usando esto están usando POST en lugar de DELETE, por lo que no podría ni debería funcionar
Alexander Derck
Creo que esto se debe a que está utilizando data(es decir, el cuerpo de la solicitud) en lugar de params(es decir, la URL de la solicitud) en el lado del cliente.
Thomas Sauvajon
Estoy de acuerdo con Alexander Derck, esto es más una tontería que una solución.
Basem Sayej