{"Mensaje" de WebApi: "se ha producido un error"} en IIS7, no en IIS Express

171

Estoy trabajando con ASP.NET MVC 4 WebApi y me divierto mucho ejecutándolo en mi computadora local en IIS Express. También configuré IIS Express para dar servicio a máquinas remotas, por lo que otras personas de mi empresa están usando mi computadora como nuestro servidor web.

Después de decidir que esta era una solución menos que óptima, decidimos colocar el WebApi en un servidor remoto después de instalar .NET 4.5. Cuando uso el violinista y envío una POST a un controlador en mi máquina local, devuelve la respuesta correcta, pero cuando cambio el dominio al servidor web que ejecuta IIS7, la misma POST devuelve un mensaje críptico

{"mensaje": "se ha producido un error"}

mensaje. Alguien tiene alguna idea de lo que podría estar pasando?

NS G
fuente
2
¿Cuál es el código de estado HTTP en la respuesta de error? Si es 500, es muy probable que la configuración del sitio web / aplicación no sea válida para la máquina remota con IIS 7. Cree un archivo HTML simple en la máquina remota, examínelo en la máquina remota si es posible para asegurarse de que se pueda ver y luego intente golpearlo desde su máquina para ver si tiene éxito o no.
Sixto Saez
Es un error 500. Gracias por la sugerencia, pero la página index.html predeterminada que proporciona WebApi funciona. También debería agregar que algunos de los servicios web API funcionan y otros no, mientras que todos funcionan en mi máquina local.
nsg
2
Deberá habilitar el seguimiento de solicitudes de IIS para obtener más detalles cuando vea un error 500. Por lo general, se produce un error 500 antes de que se inicie el enrutamiento de la API web, pero supongo que es posible activarlo por algo que está haciendo su código. Mire el registro de seguimiento de IIS y vea si eso ofrece alguna pista.
Sixto Saez
1
Es posible que pueda hacer que el servidor le brinde información de error más detallada en su respuesta iniciando la solicitud desde un navegador en la máquina del servidor (por ejemplo, utilizando una sesión de Escritorio remoto).
Jon Schneider

Respuestas:

268

El problema era una dependencia faltante que no estaba en el servidor pero estaba en mi máquina local. En nuestro caso, fue un dll Devart.Data.Linq.

Para llegar a esa respuesta, activé el rastreo de IIS para 500 errores. Eso proporcionó un poco de información, pero lo realmente útil fue en la configuración de web.config <system.web><customErrors mode="Off"/></system.web>Esto apuntó a una dependencia cargada dinámicamente que falta. Después de agregar esta dependencia y decirle que se copie localmente, el servidor comenzó a funcionar.

NS G
fuente
33
Parece que WebAPI sustituirá {"mensaje": "se ha producido un error"} por la respuesta real siempre que el código de respuesta HTTP sea 500 y los errores personalizados estén activados. Gracias por la anotación.
Paul Suart
44
Gran sugerencia sobre la configuración del modo customErrors. Me sorprende cambiar que tuvo un impacto en la salida de este tipo de errores.
Dewi Rees
1
también puede configurarlo mode="RemoteOnly"y si ejecuta la página en un navegador web en el servidor, también verá los errores sin comprometer la seguridad si el resto del sitio es accesible externamente
Simon_Weaver
¿Alguna sugerencia sobre cómo obtener este tipo de detalles de error al cambiar esa configuración no es posible (por ejemplo, los errores se deshabilitan a nivel de máquina porque la parte API está alojada en un servidor compatible con PCI)? Intenté configurar Elmah, pero desafortunadamente no está registrando nada.
RubyHaus
Este es el mejor enfoque, da suficiente información sobre un método tan genérico.
DanielV
97

Básicamente:

Use IncludeErrorDetailPolicyen su lugar si CustomErrorsno lo resuelve por usted (por ejemplo, si su pila ASP.NET es> 2012):

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy 
= IncludeErrorDetailPolicy.Always;

Nota: Tenga cuidado al devolver información detallada del error puede revelar información confidencial a los 'hackers'. Vea el comentario de Simon sobre esta respuesta a continuación.

TL; versión DR

Para mí CustomErrorsrealmente no ayudó. Ya estaba configurado en Off, pero todavía recibí un an error has occurredmensaje miserable . Supongo que la respuesta aceptada es de hace 3 años, que es mucho tiempo en la web hoy en día. Estoy usando Web API 2 y ASP.NET 5 (MVC 5) y Microsoft se ha alejado de una estrategia solo de IIS, mientras queCustomErrors es viejo skool IIS;).

De todos modos, tuve un problema en la producción que no tenía localmente. Y luego descubrí que no podía ver los errores en la pestaña Red de Chrome como podía en mi máquina de desarrollo. Al final logré resolverlo instalando Chrome en mi servidor de producción y luego buscando la aplicación allí en el servidor (por ejemplo, en 'localhost'). Luego aparecieron errores más detallados con trazas de pila y todo.

Solo después encontré este artículo de Jimmy Bogard (Nota: ¡Jimmy es el señor AutoMapper! ). Lo curioso es que su artículo también es de 2012, pero en él ya explica que CustomErrorsya no ayuda para esto, pero que PUEDE cambiar el 'Detalle de error' configurando una configuración diferente IncludeErrorDetailPolicyde WebApi global (por ejemplo WebApiConfig.cs):

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy 
= IncludeErrorDetailPolicy.Always;

Afortunadamente, también explica cómo configurarlo para que webapi (2) escuche tu CustomErrorsconfiguración. Es un enfoque bastante sensato, y le permite volver a 2012: P.

Nota: El valor predeterminado es 'LocalOnly', lo que explica por qué pude resolver el problema de la manera que describí, antes de encontrar esta publicación. Pero entiendo que no todo el mundo puede simplemente remotamente a la producción y al inicio de un navegador (sé que en su mayoría no podría hasta que decidí hacerme freelance y DevOps).

Bart
fuente
2
Ahora esto funciona. ¡Gracias! Tengo algunas pruebas de integración en memoria que fallan en el servidor de compilación, pero no localmente. Con esta configuración en mi clase de inicio, puedo tener la oportunidad de descubrir por qué.
Thomas Eyde
Parece que la configuración customError funciona con WebApi 2 cuando se aloja en IIS a través de Microsoft.AspNet.WebApi.WebHost. Los paquetes son de la versión 5.2.3, por lo ASP.NET pila manera más allá de 2012. Al establecer en Off, la API de Web cambia de errores genéricos a más detallada, que contiene la pila de llamadas, etc ...
Tom
44
Tenga cuidado al configurar esto porque puede revelar información confidencial a los 'hackers'. A menudo haré un truco rápido if (DateTime.Now < new DateTime(2017, 6, 22)) { .... }para establecer una opción como esta. Entonces puedo probarlo en producción y mañana volverá mágicamente a su comportamiento normal si olvido deshabilitarlo.
Simon_Weaver
36

Ninguna de las otras respuestas funcionó para mí.

Esto hizo: (en Startup.cs)

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();

        WebApiConfig.Register(config);

        // Here: 
        config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
    }
}

(o puede ponerlo en WebApiConfig.cs):

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API routes
        config.MapHttpAttributeRoutes();

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

        // Here: 
        config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
    }
}
samneric
fuente
¡Sí! Esta fue la única solución de trabajo para mí en Mono / Linux.
Robert II
Esto funcionó para mí en prod para una aplicación servida internamente en IIS y Windows Server.
Paul Carlton el
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always; me ayudó a encontrar que devuelvo una instancia de una entidad que no se pudo analizar porque el contexto se ha eliminado gracias
Jood jindy
12

Siempre llego a esta pregunta cuando llego a un error en el entorno de prueba y recuerdo: "Lo he hecho antes, pero puedo hacerlo directamente en web.config sin tener que modificar el código y volver a implementarlo en el entorno de prueba , pero se necesitan 2 cambios ... ¿qué fue de nuevo? "

Para futura referencia

<system.web>
   <customErrors mode="Off"></customErrors>
</system.web>

Y

<system.webServer>
  <httpErrors errorMode="Detailed" existingResponse="PassThrough"></httpErrors>
</system.webServer>
Rick Glos
fuente
11

Tuve un problema similar al publicar en el punto final de WebAPI. Al desactivar CustomErrors = Off, pude ver el error real, que es uno de los dlls faltantes.

ctong
fuente
10

En caso de que esto ayude a alguien:

Tuve un problema similar y, siguiendo las instrucciones de Nates, agregué:

<system.web>
     <customErrors mode="Off"/>
 </system.web>

Esto me mostró más información sobre el error:

"ExceptionMessage": "No se puede cargar el recurso de metadatos especificado", "ExceptionType": "System.Data.Entity.Core.MetadataException", "StackTrace": "en System.Data.Entity.Core.Metadata.Edm.MetadataArtifactLoaderCompositeResource .LoadResources (...

Esto es cuando recordé que había movido el archivo edmx a una ubicación diferente y me había olvidado de cambiar el nodo de cadenas de conexiones en la configuración (el nodo de cadenas de conexiones se colocó en un archivo separado usando "configSource", pero esa es otra historia).

Hormberg
fuente
Esto me sucedió cuando agregué OData y AutoMapper a una API web en asp.net; espero que estas palabras clave ayuden a alguien a llegar a esta publicación, e intentar / atrapar no funcionó en mi caso, así que tuve que ver el resultado en bruto
Ekus
0

Mi archivo XML swagger no se implementó en \ bin:

GlobalConfiguration.Configuration
  .EnableSwagger(c =>
  {
    c.SingleApiVersion("v1", "SwaggerDemoApi");
    c.IncludeXmlComments(string.Format(@"{0}\bin\SwaggerDemoApi.XML", 
                         System.AppDomain.CurrentDomain.BaseDirectory));
    c.DescribeAllEnumsAsStrings();
  })

http://wmpratt.com/swagger-and-asp-net-web-api-part-1/

ingrese la descripción de la imagen aquí

Tenía que establecerse en la Configuración de lanzamiento, así como en la Configuración de depuración.

RaSor
fuente
0

Si tiene <deployment retail="true"/>en machine.config de .NET Framework, no verá mensajes de error detallados. Asegúrese de que la configuración sea falsa o no esté presente.

Eric H
fuente
0

Así que probé todas las soluciones sugeridas en vano. Todo lo que hice fue configurar la aplicación desde el servidor y mostró el error completo, esto debería haber funcionado cuando configuré el modo customErrors en falso, pero no fue así. En el momento en que examiné la API del servidor, pude ver el problema.

Príncipe Tegatón
fuente