Exclusão de WebAPI não funciona - Método 405 não permitido

120

Agradeço qualquer ajuda, pois o site deve ir ao ar hoje à noite!

Eu tenho um controlador de API da web com um método Delete. O método é executado bem em minha máquina local executando o IIS Express (Windows 8), mas assim que o implantei no servidor IIS ativo (Windows Server 2008 R2), ele parou de funcionar e gerou a seguinte mensagem de erro:

Erro HTTP 405.0 - Método não permitido A página que você está procurando não pode ser exibida porque um método inválido (verbo HTTP) está sendo usado

Procurei soluções na web e implementei as mais razoáveis. Minha configuração da web tem as seguintes configurações:

<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>

Também tentei alterar os mapeamentos do manipulador e a filtragem de solicitações no IIS sem sucesso. Observe que as regras de criação de WebDAV no IIS parecem estar desabilitadas.

Todas as idéias serão muito apreciadas Obrigado.

Chris
fonte

Respostas:

199

Acabei encontrando a solução! Se você encontrar o mesmo problema, adicione o seguinte ao seu web.config

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

Eu espero que isso ajude

Chris
fonte
2
Também tive que adicionar uma remoção na seção de manipuladores de acordo com stackoverflow.com/a/6698096/254156
rrrr
3
Também trabalhei aqui. Mas alguém pode me explicar a relação com o WebDAVModule?
Boas Enkler
11
para aqueles que apenas copiam e colam: runAllManagedModulesForAllRequests = "true" não é realmente necessário e pode realmente quebrar outras coisas.
Zar Shardan
Algumas outras postagens da web irão sugerir a remoção do módulo usando a seção Módulos IIS, isso desativa, mas ainda causa este / um problema semelhante, este é o método mais confiável
Anthony Main
4
@ZarShardan (e outros) FYI: Se você remover o atributo runAllManagedModulesForAllRequests = "true", também precisará adicionar <remove name = "WebDAV" /> no nó <handlers>.
Aaron,
65

Em alguns casos, removê-lo apenas dos módulos pode produzir o próximo erro:

500.21 Handler "WebDAV" tem um módulo inválido "WebDAVModule" em sua lista de módulos

Módulo: Notificação do IIS Web Core: ExecuteRequestHandler "

solução foi sugerida aqui . Também é necessário removê-lo dos manipuladores.

<system.webServer>
    <modules>
        <remove name="WebDAVModule" />
    </modules>
    <handlers>
        <remove name="WebDAV" />
    </handlers>
</system.webServer>
aleha
fonte
1
isso funciona para mim, mas alguém pode lançar alguma luz sobre o que é WebDAV realmente?
Nazrul Muhaimin
31

No meu caso, nenhuma das soluções acima estava funcionando. Isso aconteceu porque eu tinha alterado o nome do parâmetro em meu Deletemétodo.

eu tinha

public void Delete(string Questionid)

ao invés de

public void Delete(string id)

Preciso usar o idnome porque é o nome que está declarado em meu WebApiConfigarquivo. Observe o idnome na terceira e quarta linhas:

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

Eu tenho essa solução a partir daqui .

Hugo Nava Kopp
fonte
15

O DELETEverbo Javascript para HTTP deve ser assim:

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

Você não usar algo como isto:

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

como quando você usa o POSTmétodo.

Pavel Kharibin
fonte
1
Olá @Pavel, está correto se você realmente estiver usando uma implementação totalmente RESTful. Infelizmente, nem todo mundo faz isso e é bastante comum ver desenvolvedores usando POST em vez de DELETE etc. Obrigado por esclarecer isso.
Chris,
5

Depois de tentar quase todas as soluções aqui, funcionou para mim. Adicione isso em seu arquivo de configuração de APIs

<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
fonte
Tentei muitas coisas, isso funcionou. .NET versão 4.6.1 - Obrigado.
Ketan
4

Se você estiver usando o IIS 7.0 ou uma versão posterior. Esse problema está relacionado principalmente ao módulo de extensão WebDAV no servidor IIS. isso aconteceu durante o uso da ação Publicar OU excluir.

Por favor, tente a configuração abaixo na configuração da web

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

Eu também tive o mesmo problema, estou ligando para o WebAPi e estou recebendo este erro. Adicionar a seguinte configuração em web.config para serviços resolveu meu problema

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

no arquivo web.config resolveu meu problema. É assim que eu estava ligando do lado do 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
fonte
2

Acesse o arquivo applicationHost.config (geralmente em C: \ Windows \ System32 \ inetsrv \ config) e comente a linha a seguir em applicationHost.config

1) Em <handlers>:

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

2) Comente também o módulo a seguir, sendo referido pelo manipulador acima em <modules>

<add name="WebDAVModule" />
arviman
fonte
Ou use a outra resposta stackoverflow.com/a/47907578/1754743 para REMOVER esses manipuladores em seu próprio web.config, se você não quiser (ou não puder) modificar o arquivo de configuração de toda a máquina
Ekus
2

No meu caso, esqueci de adicionar {id}ao [Route("")]e recebi o mesmo erro. Adicionar isso resolveu o problema para mim:[Route("{id}")]

Reza
fonte
Tantas horas de tempo perdido, e se não fosse por você eu ainda não consegui resolver isso ... Eu me pergunto por que ele não retorna 404: @
deadManN
1

Tive o erro 405 Método não permitido porque omiti tornar público o método Delete no controlador WebApi.

Levei muito tempo para encontrar isso (muito tempo!) Porque eu esperava um erro Não encontrado neste caso, então eu estava incorretamente assumindo que meu método Delete estava sendo negado.

O motivo de Não permitido em vez de Não encontrado é que eu também tinha um método Get para a mesma rota (que será o caso normal ao implementar REST). A função pública Get é correspondida pelo roteamento e então negada devido ao método http incorreto.

Um erro simples, eu sei, mas pode economizar algum tempo para outra pessoa.

Paul D
fonte
1

Apenas para adicionar. Se esta é a sua configuração

config.Routes.MapHttpRoute (
            nome: "DefaultApi",
            routeTemplate: "api / {controller} / {id}",
            padrões: novo {id = RouteParameter.Optional}

continue fazendo como o Hugo disse, e não defina o atributo Route para o método get do controlador, isso deu um problema no meu caso.

user6247020
fonte
0

Eu tive o problema semelhante, mas para PUT - nenhuma das outras sugestões funcionou para mim.

No entanto, eu estava usando o id intem vez do padrão string. adicionar {id:int}à rota resolveu meu problema.

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

Tivemos que adicionar cabeçalhos personalizados ao nosso web.config, pois nossa solicitação tinha vários cabeçalhos que confundiam a resposta da API.

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

O atributo [HttpPost] na parte superior do método Delete resolveu este problema para mim:

[HttpPost]
public void Delete(int Id)
{
  //Delete logic
}
Andriy Gubal
fonte
Esse pode ser o motivo pelo qual está funcionando para você. Eu estava em uma versão anterior, por volta do início de 2013, então algumas coisas foram corrigidas desde então. Fico feliz em saber que está funcionando para você.
Chris
4
Esta não é uma boa resposta para ser honesto. As pessoas cujo problema foi resolvido com isso estão usando POST em vez de DELETE, então não poderia e não deveria funcionar
Alexander Derck
Acredito que isso seja porque você está usando data(ou seja, o corpo da solicitação) em vez de params(ou seja, o url da solicitação) no lado do cliente.
Thomas Sauvajon
Eu concordo com Alexander Derck, isso é uma confusão e não uma solução.
Basem Sayej