Partilhar via


Resolver problemas com aplicações Web API2 que funcionam no Visual Studio e falham num servidor IIS de produção

Este documento explica como diagnosticar aplicações Web API2 que são implementadas num servidor IIS de produção. Resolve erros comuns HTTP 405 e 501.

Software utilizado neste tutorial

As aplicações Web API normalmente usam vários verbos HTTP: GET, POST, PUT, DELETE e, por vezes, PATCH. Dito isto, os programadores podem deparar-se com situações em que esses verbos são implementados por outro módulo IIS no seu servidor IIS de produção, o que leva a uma situação em que um controlador Web API que funciona corretamente no Visual Studio ou num servidor de desenvolvimento devolverá um erro HTTP 405 quando é implementado num servidor IIS de produção.

O que causa erros HTTP 405

O primeiro passo para aprender a diagnosticar erros HTTP 405 é perceber o que realmente significa um erro HTTP 405. O principal documento de regulação do HTTP é o RFC 2616, que define o código de estado HTTP 405 como Método Não Permitido, e descreve ainda este código de estado como uma situação em que "o método especificado no Request-Line não é permitido para o recurso identificado pelo Request-URI." Por outras palavras, o verbo HTTP não é permitido para o URL específico que um cliente HTTP solicitou.

Como breve revisão, aqui estão alguns dos métodos HTTP mais utilizados conforme definidos no RFC 2616, RFC 4918 e RFC 5789:

Método HTTP Descrição
GET Este método é usado para recuperar dados de um URI, e provavelmente é o método HTTP mais utilizado.
HEAD Este método é muito semelhante ao GET, exceto que não recupera realmente os dados do URI do pedido – simplesmente recupera o estado HTTP.
POST Este método é tipicamente usado para enviar novos dados para o URI; O POST é frequentemente utilizado para submeter dados de formulários.
PUT Este método é tipicamente usado para enviar dados brutos para o URI; O PUT é frequentemente usado para submeter dados JSON ou XML a aplicações Web API.
DELETE Este método é usado para remover dados de um URI.
OPTIONS Este método é normalmente usado para recuperar a lista de métodos HTTP suportados para um URI.
COPIAR E MOVER Estes dois métodos são usados com o WebDAV, e o seu propósito é autoexplicativo.
MKCOL Este método é usado com o WebDAV, e serve para criar uma coleção (por exemplo, um diretório) no URI especificado.
PROPFIND PROPPATCH Estes dois métodos são usados com o WebDAV, e servem para consultar ou definir propriedades para um URI.
DESTRANCA DA FECHADURA Estes dois métodos são usados com o WebDAV, e servem para bloquear/desbloquear o recurso identificado pelo URI do pedido durante a autoria.
CORREÇÃO Este método é usado para modificar um recurso HTTP existente.

Quando um destes métodos HTTP está configurado para uso no servidor, o servidor responde com o estado HTTP e outros dados apropriados para o pedido. (Por exemplo, um método GET pode receber uma resposta HTTP 200 OK , e um método PUT pode receber uma resposta HTTP 201 Created .)

Se o método HTTP não estiver configurado para uso no servidor, o servidor responderá com um erro HTTP 501 Não Implementado .

No entanto, quando um método HTTP está configurado para uso no servidor, mas foi desativado para um determinado URI, o servidor responde com um erro HTTP 405 Method Not Permited .

Exemplo de erro HTTP 405

O exemplo seguinte de pedido HTTP e resposta ilustra uma situação em que um cliente HTTP está a tentar COLOCAR valor numa aplicação Web API num servidor web, e o servidor devolve um erro HTTP que indica que o método PUT não é permitido:

Pedido HTTP:

PUT /api/values/1 HTTP/1.1
Content-type: application/json
Host: localhost
Accept: */*
Content-Length: 12

"Some Value"

Resposta HTTP:

HTTP/1.1 405 Method Not Allowed
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-Powered-By: ASP.NET
Date: Wed, 15 May 2013 02:38:57 GMT
Content-Length: 72

{"Message":"The requested resource does not support http method 'PUT'."}

Neste exemplo, o cliente HTTP enviou um pedido JSON válido para a URL de uma aplicação Web API num servidor web, mas o servidor devolveu uma mensagem de erro HTTP 405 que indica que o método PUT não foi permitido para a URL. Em contraste, se o URI do pedido não correspondesse a uma rota para a aplicação Web API, o servidor devolveria um erro HTTP 404 Não Encontrado .

Resolução de erros HTTP 405

Existem várias razões pelas quais um verbo HTTP específico pode não ser permitido, mas há um cenário principal que é a principal causa deste erro no IIS: múltiplos handlers são definidos para o mesmo verbo/método, e um dos handlers está a bloquear o esperado handler de processar o pedido. Para explicar, o IIS processa os manipuladores do primeiro ao último com base nas entradas do gestor de ordens nos ficheirosapplicationHost.config e web.config , onde a primeira combinação correspondente de caminho, verbo, recurso, etc., será usada para tratar o pedido.

O exemplo seguinte é um excerto de um ficheiro applicationHost.config para um servidor IIS que estava a devolver um erro HTTP 405 ao usar o método PUT para submeter dados a uma aplicação Web API. Neste excerto, vários handlers HTTP estão definidos, e cada handler tem um conjunto diferente de métodos HTTP para os quais está configurado – a última entrada da lista é o gestor de conteúdo estático, que é o handler padrão usado depois de os outros handlers terem tido a oportunidade de examinar o pedido:

<handlers accessPolicy="Read, Script">
   <add name="WebDAV"
      path="*"
      verb="PROPFIND,PROPPATCH,MKCOL,PUT,COPY,DELETE,MOVE,LOCK,UNLOCK"
      modules="WebDAVModule"
      resourceType="Unspecified"
      requireAccess="None" />
   <add name="ISAPI-dll"
      path="*.dll"
      verb="*"
      modules="IsapiModule"
      resourceType="File"
      requireAccess="Execute"
      allowPathInfo="true" />
   <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit"
      path="*."
      verb="GET,HEAD,POST,DEBUG"
      modules="IsapiModule"
      scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll"
      preCondition="classicMode,runtimeVersionv4.0,bitness64"
      responseBufferLimit="0" />

   <!-- Additional handlers will be defined here. -->

   <add name="StaticFile"
      path="*"
      verb="*"
      modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule"
      resourceType="Either"
      requireAccess="Read" />
</handlers>

No exemplo anterior, o handler WebDAV e o Extension-less URL Handler for ASP.NET (que é usado para Web API) estão claramente definidos para listas separadas de métodos HTTP. Note que o handler DLL ISAPI está configurado para todos os métodos HTTP, embora esta configuração não cause necessariamente um erro. No entanto, definições de configuração como esta devem ser consideradas ao tentar resolver erros HTTP 405.

No exemplo anterior, o handler DLL ISAPI não era o problema; na verdade, o problema não foi definido no ficheiroapplicationHost.config para o servidor IIS – o problema foi causado por uma entrada feita no ficheiroweb.config quando a aplicação Web API foi criada no Visual Studio. O seguinte excerto do ficheiroweb.config da aplicação mostra a localização do problema:

<handlers accessPolicy="Read, Script">
   <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
   <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" />
</handlers>

Neste excerto, o Manipulador de URLs sem Extensão para ASP.NET é redefinido para incluir métodos HTTP adicionais que serão usados com a aplicação Web API. No entanto, como um conjunto semelhante de métodos HTTP está definido para o handler WebDAV, ocorre um conflito. Neste caso específico, o handler WebDAV é definido e carregado pelo IIS, mesmo que o WebDAV esteja desativado para o site que inclui a aplicação Web API. Durante o processamento de um pedido HTTP PUT, o IIS chama o módulo WebDAV uma vez que está definido para o verbo PUT. Quando o módulo WebDAV é chamado, verifica a sua configuração e vê que está desativado, pelo que irá devolver um erro HTTP 405 Método Não Permitido para qualquer pedido que se assemelhe a um pedido WebDAV. Para resolver este problema, deve remover o WebDAV da lista de módulos HTTP do site onde a sua aplicação Web API está definida. O exemplo seguinte mostra como isso poderia ser:

<handlers accessPolicy="Read, Script">
   <remove name="WebDAV" />
   <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
   <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" />
</handlers>

Este cenário é frequentemente encontrado depois de uma aplicação ser publicada de um ambiente de desenvolvimento para um ambiente de produção IIS, e isto ocorre porque a lista de handlers/módulos é diferente entre os ambientes de desenvolvimento e produção. Por exemplo, se estiver a usar o Visual Studio 2012 ou posterior para desenvolver uma aplicação Web API, o IIS Express é o servidor web predefinido para testes. Este servidor web de desenvolvimento é uma versão reduzida da funcionalidade completa do IIS que vem incluída num produto servidor, e este servidor web de desenvolvimento contém algumas alterações que foram adicionadas para cenários de desenvolvimento. Por exemplo, o módulo WebDAV é frequentemente instalado num servidor web de produção que executa a versão completa do IIS, embora possa não estar em uso. A versão de desenvolvimento do IIS, (IIS Express), instala o módulo WebDAV, mas as entradas do módulo WebDAV são intencionalmente comentadas nas definições, de modo que o módulo WebDAV nunca é carregado no IIS Express, a menos que modifique as configurações do seu IIS Express para adicionar a função WebDAV à instalação do IIS Express. Como resultado, a sua aplicação web pode funcionar corretamente no seu computador de desenvolvimento, mas pode encontrar erros HTTP 405 ao publicar a sua aplicação Web API no seu servidor web IIS de produção.

Erros HTTP 501

  • Indica que a funcionalidade específica não foi implementada no servidor.
  • Normalmente significa que não existe nenhum handler definido nas definições do IIS que corresponda ao pedido HTTP:
    • Provavelmente indica que algo não foi instalado corretamente no IIS ou
    • Algo alterou as definições do IIS para que não haja handlers definidos que suportem o método HTTP específico.

Para resolver esse problema, terias de reinstalar qualquer aplicação que tente usar um método HTTP para o qual não tenha definições correspondentes de módulo ou handler.

Resumo

Erros HTTP 405 são causados quando um método HTTP não é permitido por um servidor web para uma URL solicitada. Esta condição é frequentemente observada quando um determinado handler foi definido para um verbo específico, e esse handler está a sobrepor-se ao handler que espera que processe o pedido.