WebApis {"message": "ein Fehler ist aufgetreten"} auf IIS7, nicht in IIS Express

171

Ich arbeite mit ASP.NET MVC 4 WebApi und habe viel Spaß damit, es auf meinem lokalen Computer unter IIS Express auszuführen. Ich habe IIS Express so konfiguriert, dass es auch Remotecomputer bedient. Daher verwenden andere in meinem Unternehmen meinen Computer als Webserver.

Nachdem wir entschieden hatten, dass dies eine nicht optimale Lösung war, entschieden wir uns, WebApi nach der Installation von .NET 4.5 auf einem Remote-Server zu installieren. Wenn ich Fiddler verwende und einen POST an einen Controller auf meinem lokalen Computer sende, wird die richtige Antwort zurückgegeben. Wenn ich jedoch die Domäne auf den Webserver ändere, auf dem IIS7 ausgeführt wird, gibt derselbe POST eine kryptische Antwort zurück

{"message": "ein Fehler ist aufgetreten"}

Botschaft. Hat jemand eine Idee, was los sein könnte?

nsg
quelle
2
Wie lautet der HTTP-Statuscode in der Fehlerantwort? Wenn es 500 ist, ist es sehr wahrscheinlich, dass die Website- / Anwendungskonfiguration für den Remotecomputer mit IIS 7 ungültig ist. Erstellen Sie eine einfache HTML-Datei auf dem Remotecomputer, durchsuchen Sie sie nach Möglichkeit auf dem Remotecomputer, um sicherzustellen, dass sie angezeigt werden kann, und versuchen Sie es dann um es von Ihrem Computer aus zu treffen, um zu sehen, ob es erfolgreich ist oder nicht.
Sixto Saez
Es ist ein 500-Fehler. Vielen Dank für den Vorschlag, aber die von WebApi bereitgestellte Standardseite index.html funktioniert. Außerdem sollte hinzugefügt werden, dass einige der API-Webservices funktionieren und andere nicht, während alle auf meinem lokalen Computer funktionieren.
nsg
2
Sie müssen die IIS-Anforderungsverfolgung aktivieren , um genauere Informationen zu erhalten, wenn ein 500-Fehler angezeigt wird. Ein 500-Fehler tritt normalerweise vor dem Start des Web-API-Routings auf, aber ich denke, es ist möglich, ihn durch etwas auszulösen, das Ihr Code tut. Sehen Sie sich die IIS-Ablaufverfolgungsprotokollierung an und prüfen Sie, ob dies Hinweise bietet.
Sixto Saez
1
Möglicherweise können Sie den Server dazu bringen, Ihnen ausführlichere Fehlerinformationen in seiner Antwort zu geben, indem Sie die Anforderung über einen Browser auf dem Servercomputer selbst initiieren (z. B. mithilfe einer Remotedesktopsitzung).
Jon Schneider

Antworten:

268

Das Problem war eine fehlende Abhängigkeit, die sich nicht auf dem Server befand, sondern auf meinem lokalen Computer. In unserem Fall war es eine Devart.Data.Linq-DLL.

Um zu dieser Antwort zu gelangen, habe ich die IIS-Ablaufverfolgung für 500 Fehler aktiviert. Das gab ein paar Informationen, aber das wirklich Hilfreiche war in der web.config-Einstellung. <system.web><customErrors mode="Off"/></system.web>Dies deutete auf eine fehlende dynamisch geladene Abhängigkeit hin. Nachdem diese Abhängigkeit hinzugefügt und angewiesen wurde, lokal kopiert zu werden, begann der Server zu arbeiten.

nsg
quelle
33
Es sieht so aus, als würde WebAPI die tatsächliche Antwort durch {"message": "ein Fehler ist aufgetreten"} ersetzen, wenn der HTTP-Antwortcode 500 lautet und benutzerdefinierte Fehler aktiviert sind. Danke für den Zeiger.
Paul Suart
4
Toller Vorschlag zum Einstellen des customErrors-Modus. Ich bin überrascht, dass sich Änderungen geändert haben, die sich auf die Ausgabe dieser Art von Fehlern ausgewirkt haben.
Dewi Rees
1
Sie können es auch auf einstellen mode="RemoteOnly"und wenn Sie die Seite auf einem Webbrowser auf dem Server ausführen, werden die Fehler auch
angezeigt
Irgendwelche Vorschläge, wie diese Art von Fehlerdetails beim Ändern dieser Einstellung abgerufen werden können, sind nicht möglich (z. B. werden Fehler auf Computerebene deaktiviert, weil der API-Teil auf einem PCI-kompatiblen Server gehostet wird)? Ich habe versucht, Elmah einzurichten, aber es wird leider nichts protokolliert.
RubyHaus
Dies ist der beste Ansatz, gibt genügend Informationen über eine solche generische Methode.
DanielV
97

Grundsätzlich:

Verwenden Sie IncludeErrorDetailPolicystattdessen, wenn CustomErrorses für Sie nicht gelöst wird (z. B. wenn Ihr ASP.NET-Stack> 2012 ist):

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy 
= IncludeErrorDetailPolicy.Always;

Hinweis: Seien Sie vorsichtig, wenn Sie detaillierte Fehlerinformationen zurückgeben, die vertrauliche Informationen an "Hacker" weitergeben können. Siehe Simons Kommentar zu dieser Antwort unten.

TL; DR-Version

Für mich CustomErrorshat das nicht wirklich geholfen. Es war bereits eingestellt Off, aber ich bekam immer noch nur eine dürftige an error has occurredNachricht. Ich denke, die akzeptierte Antwort stammt von vor 3 Jahren, was heutzutage eine lange Zeit im Web ist. Ich verwende Web API 2 und ASP.NET 5 (MVC 5) und Microsoft hat sich von einer Nur-IIS-Strategie entfernt, während CustomErrorses sich um altes Skool-IIS handelt;).

Wie auch immer, ich hatte ein Produktionsproblem, das ich vor Ort nicht hatte. Und dann stellte ich fest, dass ich die Fehler auf der Registerkarte "Netzwerk" von Chrome nicht so sehen konnte wie auf meinem Entwicklungscomputer. Am Ende gelang es mir, das Problem zu lösen, indem ich Chrome auf meinem Produktionsserver installierte und dann auf dem Server selbst zu der dortigen App navigierte (z. B. auf 'localhost'). Dann traten detailliertere Fehler mit Stapelspuren und allem auf.

Erst danach fand ich diesen Artikel von Jimmy Bogard (Hinweis: Jimmy ist Herr AutoMapper! ). Das Lustige ist, dass sein Artikel ebenfalls aus dem Jahr 2012 stammt, aber darin erklärt er bereits, dass CustomErrorsdies nicht mehr hilft, sondern dass Sie das ' IncludeErrorDetailPolicyFehlerdetail ' ändern können, indem Sie in der globalen WebApi-Konfiguration eine andere festlegen (z. B. WebApiConfig.cs):

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy 
= IncludeErrorDetailPolicy.Always;

Zum Glück erklärt er auch, wie man es einrichtet, dass webapi (2) Ihre CustomErrorsEinstellungen hört . Das ist ein ziemlich vernünftiger Ansatz, mit dem Sie bis 2012 zurückkehren können: P.

Hinweis: Der Standardwert ist 'LocalOnly'. Dies erklärt, warum ich das Problem so lösen konnte, wie ich es beschrieben habe, bevor ich diesen Beitrag gefunden habe. Aber ich verstehe, dass nicht jeder einfach per Fernzugriff zur Produktion und zum Starten eines Browsers gelangen kann (ich weiß, dass ich es meistens nicht konnte, bis ich mich entschied, freiberuflich und DevOps zu arbeiten).

Bart
quelle
2
Das funktioniert jetzt. Danke dir! Ich habe einige In-Memory-Integration-Owin-Tests, die auf dem Build-Server fehlschlagen, aber nicht lokal. Mit dieser Einstellung in meiner Startup-Klasse kann ich möglicherweise herausfinden, warum.
Thomas Eyde
Es scheint, dass die Einstellung customError mit WebApi 2 funktioniert, wenn sie in IIS über Microsoft.AspNet.WebApi.WebHost gehostet wird. Die Pakete sind Version 5.2.3, also ASP.NET-Stack weit nach 2012. Durch Setzen auf Off wechselt die Web-API von generischen Fehlern zu detaillierteren, die den Call-Stack usw. enthalten.
Tom
4
Seien Sie vorsichtig, da dies vertrauliche Informationen für "Hacker" offenlegen kann. Ich mache oft einen schnellen Hack if (DateTime.Now < new DateTime(2017, 6, 22)) { .... }, um eine Option wie diese festzulegen. Dann kann ich es in der Produktion testen und morgen wird es auf magische Weise zum normalen Verhalten zurückkehren, wenn ich vergesse, es zu deaktivieren.
Simon_Weaver
36

Keine der anderen Antworten hat bei mir funktioniert.

Dies tat: (in Startup.cs)

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

        WebApiConfig.Register(config);

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

(oder Sie können es in WebApiConfig.cs ablegen):

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
quelle
Ja!, Dies war die einzige funktionierende Lösung für mich unter Mono / Linux.
Robert II
Dies funktionierte für mich als Produkt für eine intern bereitgestellte App auf IIS und Windows Server.
Paul Carlton
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always; hat mir geholfen herauszufinden, dass ich eine Instanz einer Entität zurückgebe, die nicht analysiert werden konnte, weil der Kontext entsorgt wurde. Danke
Jood jindy
12

Ich komme immer zu dieser Frage, wenn ich in der Testumgebung auf einen Fehler stoße und mich erinnere: "Ich habe dies bereits getan, aber ich kann es direkt in der web.config tun, ohne Code ändern und erneut in der Testumgebung bereitstellen zu müssen , aber es dauert 2 Änderungen ... was war es wieder? "

Zum späteren Nachschlagen

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

UND

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

Ich hatte ein ähnliches Problem beim Posten auf dem WebAPI-Endpunkt. Durch Ausschalten von CustomErrors = Off konnte ich den tatsächlichen Fehler sehen, bei dem eine der DLLs fehlte.

ctong
quelle
10

Falls dies jemandem hilft:

Ich hatte ein ähnliches Problem und befolgte die Anweisungen von Nates, die ich hinzugefügt habe:

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

Dies zeigte mir mehr Informationen über den Fehler:

"ExceptionMessage": "Die angegebene Metadatenressource kann nicht geladen werden.", "ExceptionType": "System.Data.Entity.Core.MetadataException", "StackTrace": "at System.Data.Entity.Core.Metadata.Edm.MetadataArtifactLoaderCompositeResource .LoadResources (...

Zu diesem Zeitpunkt fiel mir ein, dass ich die edmx-Datei an einen anderen Speicherort verschoben und vergessen hatte, den Verbindungsstring-Knoten in der Konfiguration zu ändern (der Verbindungsstring-Knoten wurde mit "configSource" in einer separaten Datei abgelegt, aber das ist eine andere Geschichte).

Hormberg
quelle
Dies ist mir passiert, als ich OData und AutoMapper zu einer Web-API in asp.net hinzugefügt habe - hoffentlich helfen diese Schlüsselwörter jemandem, diesen Beitrag zu erreichen, und try / catch hat in meinem Fall nicht funktioniert, sodass ich das
Rohergebnis
0

Meine Swagger-XML-Datei wurde nicht in \ bin bereitgestellt:

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/

Geben Sie hier die Bildbeschreibung ein

Es musste sowohl in der Release-Konfiguration als auch in der Debug-Konfiguration festgelegt werden.

RaSor
quelle
0

Wenn Sie <deployment retail="true"/>in der Datei machine.config Ihres .NET Frameworks keine detaillierten Fehlermeldungen sehen. Stellen Sie sicher, dass die Einstellung falsch oder nicht vorhanden ist.

Eric H.
quelle
0

Also habe ich alle vorgeschlagenen Lösungen ohne Erfolg ausprobiert. Alles, was ich getan habe, war, die App vom Server aus auszuführen und den Fehler vollständig anzuzeigen. Dies hätte funktionieren sollen, wenn ich den customErrors-Modus auf false gesetzt habe, aber dies war nicht der Fall. In dem Moment, als ich die API vom Server aus durchsuchte, konnte ich das Problem erkennen.

Prinz Tegaton
quelle