{"Message" de WebApi: "une erreur s'est produite"} sur IIS7, pas dans IIS Express

171

Je travaille avec ASP.NET MVC 4 WebApi et je m'amuse beaucoup en l'exécutant sur mon ordinateur local sur IIS Express. J'ai configuré IIS Express pour qu'il serve également des machines distantes, et d'autres membres de mon entreprise utilisent mon ordinateur comme serveur Web.

Après avoir décidé qu'il s'agissait d'une solution moins qu'optimale, nous avons décidé de placer WebApi sur un serveur distant après l'installation de .NET 4.5. Lorsque j'utilise un violoniste et que j'envoie un POST à ​​un contrôleur sur ma machine locale, il renvoie la réponse correcte, mais lorsque je change de domaine sur le serveur Web exécutant IIS7, le même POST renvoie un cryptique

{"message": "une erreur s'est produite"}

message. Quelqu'un a une idée de ce qui pourrait se passer?

NS g
la source
2
Quel est le code d'état HTTP sur la réponse d'erreur? Si c'est 500, il est très probable que la configuration du site Web / de l'application ne soit pas valide pour la machine distante avec IIS 7. Créez un simple fichier HTML sur la machine distante, parcourez-le sur la machine distante si possible pour vous assurer qu'il peut être visualisé, puis essayez pour le frapper depuis votre machine pour voir s'il réussit ou non.
Sixto Saez
C'est une erreur de 500. Merci pour la suggestion, mais la page index.html par défaut fournie par WebApi fonctionne. Il convient également d'ajouter que certains services Web d'API fonctionnent et d'autres non, alors que tous fonctionnent sur ma machine locale.
nsg
2
Vous devrez activer le suivi des demandes IIS pour obtenir plus de détails lorsque vous voyez une erreur 500. Une erreur 500 se produit généralement avant que le routage de l'API Web ne démarre, mais je suppose qu'il est possible de la déclencher par quelque chose que fait votre code. Regardez la journalisation de trace IIS et voyez si cela offre des indices.
Sixto Saez
1
Vous pourrez peut-être demander au serveur de vous donner des informations d'erreur plus détaillées dans sa réponse en lançant la requête à partir d'un navigateur sur la machine serveur elle-même (par exemple en utilisant une session Bureau à distance).
Jon Schneider

Réponses:

268

Le problème était une dépendance manquante qui n'était pas sur le serveur mais sur ma machine locale. Dans notre cas, il s'agissait d'une DLL Devart.Data.Linq.

Pour obtenir cette réponse, j'ai activé le traçage IIS pour 500 erreurs. Cela a donné un peu d'informations, mais la chose vraiment utile était dans le paramétrage de web.config le <system.web><customErrors mode="Off"/></system.web>Ceci indiquait une dépendance chargée dynamiquement manquante. Après avoir ajouté cette dépendance et lui avoir dit d'être copiée localement, le serveur a commencé à fonctionner.

NS g
la source
33
On dirait que WebAPI remplacera {"message": "une erreur s'est produite"} pour la réponse réelle chaque fois que le code de réponse HTTP est 500 et que des erreurs personnalisées sont activées. Merci pour le pointeur.
Paul Suart
4
Excellente suggestion sur la configuration du mode customErrors. Je suis surpris de changer qui a eu un impact sur la sortie de ce genre d'erreurs.
Dewi Rees
1
vous pouvez également le définir sur mode="RemoteOnly"et si vous exécutez la page sur un navigateur Web sur le serveur, vous verrez également les erreurs sans compromettre la sécurité si le reste du site est accessible de l'extérieur
Simon_Weaver
Des suggestions sur la façon d'obtenir ce type de détail d'erreur lorsque la modification de ce paramètre n'est pas possible (par exemple, les erreurs sont désactivées au niveau de la machine car la partie API est hébergée sur un serveur compatible PCI)? J'ai essayé de configurer Elmah, mais il n'enregistre malheureusement rien.
RubyHaus
C'est la meilleure approche, donne suffisamment d'informations sur une telle méthode générique.
DanielV
97

Fondamentalement:

Utilisez à la IncludeErrorDetailPolicyplace si CustomErrorsne le résout pas pour vous (par exemple, si votre pile ASP.NET est> 2012):

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy 
= IncludeErrorDetailPolicy.Always;

Remarque: soyez prudent, le retour d'informations détaillées sur les erreurs peut révéler des informations sensibles aux «pirates». Voir le commentaire de Simon sur cette réponse ci-dessous.

TL; version DR

Pour moi, cela CustomErrorsn'a pas vraiment aidé. C'était déjà réglé Off, mais je n'ai toujours reçu qu'un maigre an error has occurredmessage. Je suppose que la réponse acceptée date d'il y a 3 ans, ce qui est une longue période dans le monde de nos jours. J'utilise Web API 2 et ASP.NET 5 (MVC 5) et Microsoft s'est éloigné d'une stratégie IIS uniquement, tandis queCustomErrors ancien skool IIS;).

Quoi qu'il en soit, j'ai eu un problème de production que je n'avais pas localement. Et puis j'ai constaté que je ne pouvais pas voir les erreurs dans l'onglet Réseau de Chrome comme je le pouvais sur ma machine de développement. En fin de compte, j'ai réussi à le résoudre en installant Chrome sur mon serveur de production, puis en naviguant vers l'application sur le serveur lui-même (par exemple sur 'localhost'). Ensuite, des erreurs plus détaillées sont apparues avec des traces de pile et tout.

C'est seulement après que j'ai trouvé cet article de Jimmy Bogard (Note: Jimmy est M. AutoMapper! ). Ce qui est drôle, c'est que son article date également de 2012, mais il y explique déjà que cela CustomErrorsn'aide plus pour cela, mais que vous POUVEZ changer le `` détail de l'erreur '' en définissant un autre IncludeErrorDetailPolicydans la configuration globale de WebApi (par exemple WebApiConfig.cs):

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy 
= IncludeErrorDetailPolicy.Always;

Heureusement, il explique également comment le configurer pour que webapi (2) écoute vos CustomErrorsparamètres. C'est une approche assez sensée, et cela vous permet de remonter à 2012: P.

Remarque: la valeur par défaut est «LocalOnly», ce qui explique pourquoi j'ai pu résoudre le problème de la manière dont je l'ai décrit, avant de trouver ce message. Mais je comprends que tout le monde ne peut pas simplement produire à distance et démarrer un navigateur (je sais que je ne pourrais surtout pas jusqu'à ce que je décide de devenir indépendant ET DevOps).

Bart
la source
2
Maintenant, cela fonctionne. Je vous remercie! J'ai quelques tests en mémoire-intégration-owin-type qui échouent sur le serveur de construction, mais pas localement. Avec ce paramètre dans ma classe de démarrage, j'ai peut-être une chance de comprendre pourquoi.
Thomas Eyde
Il semble que le paramètre customError fonctionne avec WebApi 2 lorsqu'il est hébergé dans IIS via Microsoft.AspNet.WebApi.WebHost. Les packages sont la version 5.2.3, donc la pile ASP.NET après 2012. En le définissant sur Off, l'API Web passe d'erreurs génériques à plus détaillées, contenant la pile d'appels, etc ...
Tom
4
Soyez prudent en définissant ceci car cela peut révéler des informations sensibles aux «pirates». Je vais souvent faire un piratage rapide, comme if (DateTime.Now < new DateTime(2017, 6, 22)) { .... }définir une option comme celle-ci. Ensuite, je peux le tester en production et demain il reviendra comme par magie à son comportement normal si j'oublie de le désactiver.
Simon_Weaver
36

Aucune des autres réponses n'a fonctionné pour moi.

Cela a fait: (dans Startup.cs)

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

        WebApiConfig.Register(config);

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

(ou vous pouvez le mettre dans 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
la source
Oui! C'était la seule solution qui fonctionnait pour moi sur Mono / Linux.
Robert II
Cela a fonctionné pour moi sur la production d'une application servie en interne sur IIS et Windows Server.
Paul Carlton
config.IncludeErrorDetailPolicy = InclureErrorDetailPolicy.Always; m'a aidé à trouver que je renvoie une instance d'une entité qui n'a pas pu être analysée parce que le contexte a été éliminé merci
Jood jindy
12

J'arrive toujours à cette question lorsque je rencontre une erreur dans l'environnement de test et que je me souviens: «J'ai déjà fait cela, mais je peux le faire directement dans le web.config sans avoir à modifier le code et à redéployer vers l'environnement de test , mais il faut 2 changements ... qu'est-ce que c'était encore? "

Pour référence future

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

ET

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

J'ai eu un problème similaire lors de la publication sur le point de terminaison WebAPI. En tournant le CustomErrors = Off, j'ai pu voir l'erreur réelle qui est l'une des dll manquantes.

ctong
la source
10

Au cas où cela aiderait quelqu'un:

J'ai eu un problème similaire et en suivant les instructions de Nates, j'ai ajouté:

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

Cela m'a montré plus d'informations sur l'erreur:

"ExceptionMessage": "Impossible de charger la ressource de métadonnées spécifiée.", "ExceptionType": "System.Data.Entity.Core.MetadataException", "StackTrace": "à System.Data.Entity.Core.Metadata.Edm.MetadataArtifactLoaderCompositeResource .LoadResources (...

C'est à ce moment que je me suis souvenu que j'avais déplacé le fichier edmx vers un autre emplacement et que j'avais oublié de changer le nœud connectionstrings dans la configuration (le nœud connectionsstrings a été placé dans un fichier séparé en utilisant "configSource", mais c'est une autre histoire).

Hormberg
la source
Cela m'est arrivé lors de l'ajout d'OData et d'AutoMapper à une api Web dans asp.net - j'espère que ces mots-clés aideront quelqu'un à atteindre ce message, et try / catch n'a pas fonctionné dans mon cas, j'ai donc dû voir le résultat brut
Ekus
0

Mon fichier XML swagger n'a pas été déployé dans \ 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/

entrez la description de l'image ici

Il devait être défini dans la configuration de publication ainsi que dans la configuration de débogage.

RaSor
la source
0

Si vous en avez <deployment retail="true"/>dans le fichier machine.config de .NET Framework, vous ne verrez pas de messages d'erreur détaillés. Assurez-vous que ce paramètre est faux ou absent.

Eric H
la source
0

J'ai donc essayé toutes les solutions suggérées en vain. Tout ce que j'ai fait a été de configurer l'application à partir du serveur et d'afficher l'erreur dans son intégralité.Cela aurait dû fonctionner lorsque j'ai défini le mode customErrors sur false, mais ce n'est pas le cas. Au moment où j'ai parcouru l'API du serveur, j'ai pu voir le problème.

Prince Tegaton
la source