Solución de problemas de aplicaciones de API2 web que funcionan en Visual Studio y que fallan en un servidor IIS de producción

Esta documentación explica cómo solucionar problemas de aplicaciones web API2 que se implementan en un servidor IIS de producción. Habla de errores HTTP 405 y 501 comunes.

Software utilizado en este tutorial

Las aplicaciones de API web suelen usar varios verbos HTTP: GET, POST, PUT, DELETE y, a veces, PATCH. Dicho esto, los desarrolladores pueden encontrarse en situaciones en las que otro módulo IIS implemente esos verbos en su servidor IIS de producción, lo que provoca que un controlador de API web que funciona correctamente en Visual Studio o en un servidor de desarrollo devuelva un error HTTP 405 cuando se implementa en un servidor IIS de producción.

¿Qué provoca errores HTTP 405?

El primer paso para aprender a solucionar errores HTTP 405 es entender qué significa realmente un error HTTP 405. El principal documento regulador de HTTP es RFC 2616, que define el código de estado HTTP 405 como Método no permitido y describe aún más este código de estado como una situación en la que "el método especificado en la línea de solicitud no está permitido para el recurso identificado por solicitud-URI". En otras palabras, el verbo HTTP no está permitido para la dirección URL específica que ha solicitado un cliente HTTP.

Como breve revisión, estos son varios de los métodos HTTP más usados, tal como se define en RFC 2616, RFC 4918 y RFC 5789:

Método de HTTP Descripción
GET Este método se usa para recuperar datos de un URI y probablemente sea el método HTTP más usado.
HEAD Este método es muy similar al método GET, pero realmente no recupera los datos del URI de solicitud, sino que simplemente recupera el estado HTTP.
POST Este método se usa normalmente para enviar nuevos datos al URI,POST se suele usar para enviar datos de formulario.
PUT Este método se usa normalmente para enviar datos sin procesar al URI, PUT se usa a menudo para enviar datos JSON o XML a aplicaciones API web.
DELETE Este método se usa para quitar datos de un URI.
OPTIONS Este método se usa normalmente para recuperar la lista de métodos HTTP que se admiten para un URI.
COPY MOVE Estos dos métodos se usan con WebDAV y su propósito es obvio: copiar y mover.
MKCOL Este método se usa con WebDAV y se usa para crear una colección (por ejemplo, un directorio) en el URI especificado.
PROPFIND PROPPATCH Estos dos métodos se usan con WebDAV y se usan para consultar o establecer propiedades para un URI.
LOCK UNLOCK Estos dos métodos se utilizan con WebDAV y se usan para bloquear o desbloquear el recurso identificado por el URI de solicitud al crear.
PATCH Este método se usa para modificar un recurso HTTP existente.

Cuando uno de estos métodos HTTP está configurado para su uso en el servidor, el servidor responderá con el estado HTTP y otros datos adecuados para la solicitud. (Por ejemplo, un método GET podría recibir un HTTP 200 OK y un método PUT podría recibir una respuesta HTTP 201 Created).

Si el método HTTP no está configurado para su uso en el servidor, el servidor responderá con un error HTTP 501 Sin crear.

Sin embargo, cuando se configura un método HTTP para su uso en el servidor, pero se ha deshabilitado para un URI determinado, el servidor responderá con un error HTTP 405 Método no permitido.

Error HTTP 405 de ejemplo

En el ejemplo siguiente, la solicitud HTTP y la respuesta muestran una situación en la que un cliente HTTP intenta poner el valor a una aplicación de API web en un servidor web y el servidor devuelve un error HTTP que indica que no se permite el método PUT:

Solicitud HTTP:

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

"Some Value"

Respuesta 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'."}

En este ejemplo, el cliente HTTP envió una solicitud JSON válida a la URL de una aplicación de API web en un servidor web, pero el servidor devolvió un mensaje de error HTTP 405 que indica que el método PUT no estaba permitido para la URL. Por el contrario, si el URI de solicitud no coincide con una ruta para la aplicación de API web, el servidor devolvería un error HTTP 404 Not Found.

Resolver errores HTTP 405

Hay varias razones por las que no se puede permitir un verbo HTTP específico, pero hay un escenario predominante que es la causa principal de este error en IIS: se definen varios controladores para el mismo verbo o método, y uno de los controladores bloquea el controlador esperado para procesar la solicitud. A modo de explicación, IIS procesa controladores de primero a último en función de las entradas del controlador de pedidos en los archivos applicationHost.config yweb.config, donde se usará la primera combinación coincidente de ruta de acceso, verbo, recurso, etc., para controlar la solicitud.

El ejemplo siguiente es un extracto de un archivo applicationHost.config para un servidor IIS que devolvía un error HTTP 405 al usar el método PUT para enviar datos a una aplicación de API web. En este extracto, se definen varios controladores HTTP y cada controlador tiene un conjunto diferente de métodos HTTP para los que está configurado: la última entrada de la lista es el controlador de contenido estático, que es el controlador de contenido predeterminado que se usa después de que los otros controladores hayan tenido la oportunidad de examinar la solicitud.

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

En el ejemplo anterior, el controlador WebDAV y el controlador de direcciones URL sin extensión para ASP.NET (que se usa para la API web) se definen claramente para listas independientes de métodos HTTP. Tenga en cuenta que el controlador DLL ISAPI está configurado para todos los métodos HTTP, aunque esta configuración no provocará necesariamente un error. No obstante, las opciones de configuración como esta deben tenerse en cuenta al solucionar errores HTTP 405.

En el ejemplo anterior, el controlador DLL de ISAPI no era el problema. De hecho, el problema no se definió en el archivo applicationHost.config para el servidor IIS; el problema se debió a una entrada que se realizó en el archivo web.config cuando se creó la aplicación de API web en Visual Studio. El siguiente extracto del archivo web.config de la aplicación muestra la ubicación del 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>

En este extracto, el controlador de direcciones URL sin extensión para ASP.NET se vuelve a definir para incluir métodos HTTP adicionales que se usarán con la aplicación de API web. Sin embargo, se produce un conflicto porque se define un conjunto similar de métodos HTTP para el controlador de WebDAV. En este caso específico, IIS define y carga el controlador WebDAV, aunque WebDAV esté deshabilitado para el sitio web que incluye la aplicación de API web. Durante el procesamiento de una solicitud HTTP PUT, IIS llama al módulo WebDAV, ya que está definido para el verbo PUT. Cuando se llama al módulo WebDAV, este comprueba su configuración y ve que está deshabilitado, por lo que devolverá un error HTTP 405 Método no permitido para cualquier solicitud similar a una solicitud webDAV. Para resolver este problema, debe quitar WebDAV de la lista de módulos HTTP del sitio web donde se define la aplicación de API web. En este ejemplo se muestra el aspecto que podría tener:

<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 escenario suele encontrarse después de publicar una aplicación desde un entorno de desarrollo en un entorno de producción de IIS y esto se produce porque la lista de controladores o módulos es diferente entre los entornos de desarrollo y producción. Por ejemplo, si usa Visual Studio 2012 o posterior para desarrollar una aplicación de API web, IIS Express es el servidor web predeterminado para las pruebas. Este servidor web de desarrollo es una versión escalada de la funcionalidad completa de IIS que se suministra en un producto de servidor y este servidor web de desarrollo contiene algunos cambios que se agregaron para escenarios de desarrollo. Por ejemplo, el módulo WebDAV se instala a menudo en un servidor web de producción que ejecuta la versión completa de IIS, aunque puede que no esté en uso. La versión de desarrollo de IIS, (IIS Express), instala el módulo WebDAV, pero las entradas del módulo WebDAV se comentan intencionadamente, por lo que el módulo WebDAV nunca se carga en IIS Express a menos que usted modifique específicamente los valores de configuración de IIS Express para agregar funcionalidad de WebDAV a la instalación de IIS Express. Así, la aplicación web puede funcionar correctamente en el equipo de desarrollo, pero es posible que encuentre errores HTTP 405 al publicar la aplicación de API web en el servidor web IIS de producción.

Errores HTTP 501

  • Indica que la funcionalidad específica no se ha implementado en el servidor.
  • Normalmente significa que no hay ningún controlador definido en la configuración de IIS que coincida con la solicitud HTTP:
    • Probablemente indica que algo no se instaló correctamente en IIS o
    • Algo ha modificado la configuración de IIS para que no haya controladores definidos que admitan el método HTTP específico.

Para resolver ese problema, tendría que volver a instalar cualquier aplicación que intente usar un método HTTP para el que no tenga definiciones de módulo o controlador correspondientes.

Resumen

Los errores HTTP 405 se producen cuando un servidor web no permite un método HTTP para una dirección URL solicitada. Esta condición se suele ver cuando se ha definido un controlador determinado para un verbo específico y ese controlador invalida el controlador que espera procesar la solicitud.