ASP.NET-Web-API: Nicht beschreibender 500 Internal Server Error

72

Wie der Titel schon sagt, habe ich 500 interne Serverfehler von der GET-Anforderung bis zu einer IQueryable-Aktion. Der Hauptteil des Fehlers ist leer. Dieser Fehler tritt auf, nachdem meine Aktion das Ergebnis zurückgegeben hat.

Ich verwende ASP.NET Web API RC.

Wie kann ich eine Stapelverfolgung dieses Fehlers erhalten?

seltsam
quelle
2
Berat, Wie gesagt, eine Ausnahme tritt auf, nachdem meine Aktion das Ergebnis zurückgegeben hat. Ich gehe davon aus, dass es passiert, wenn Web Api versucht, meine Sammlung zu serialisieren. Aber ich möchte nicht annehmen, ich möchte genau wissen, was los ist.
Oddy
Ich habe dies als bekanntes Problem in einer der älteren Versionen gesehen. Welches benutzt du, Beta oder RC?
Aliostad
1
@ stever-b Ich habe den XML-Formatierer in Global.asax gelöscht. Aber in meinem Fall hat der XML-Formatierer Entitäten korrekt serialisiert. Ich konnte das durch GET im Browser sehen. Die Verwendung von getJSON aus jquery-Ergebnissen im JSON-Formatierer wurde von WebAPI ausgewählt, und hier geht vermutlich etwas schief.
Oddy
4
Dies ist ein Fehler in RC. Es gibt keine Möglichkeit, den Fehler (Ausnahmemeldung) im Antwortinhalt zurückzugeben, wenn Sie eine URL Ihrer API aus der Ferne anfordern. Die Inhaltslänge ist immer Null. Ich habe sowohl IncludeErrorDetailPolicy als auch das Überschreiben der ExceptionFilterAttribute OnException versucht, aber es hat nicht remote funktioniert, unabhängig davon, ob die benutzerdefinierten Fehler in der web.config auf "Off" gesetzt wurden. Die Ausnahme trat auf, als ich rdp auf dem Remote-Server verwendete und eine Anforderung auf dem lokalen Host nur mit der Einstellung IncludeErrorDetailPolicy ausführte. Daher glaube ich leider, dass Sie den Stack-Trace des Fehlers noch nicht erhalten können.
Cleftheris
1
@sham Ja, ich habe zu Java Tech Stack
gewechselt

Antworten:

9

Nach RC wurde dieses Problem behoben und Sie erhalten neben dem 500 Internal Server Error auch Fehlerdetails. (Dieses Problem wurde jedoch nur für Webhost-Szenarien behoben.)

Sie können Folgendes tun, um die Details der tatsächlichen Ausnahme abzurufen, die während der WriteToStream-Methode eines Formatierers auftreten kann.

ObjectContent<IEnumerable<Product>> responseContent = new ObjectContent<IEnumerable<Product>>(db.Products.Include(p => p.ProductSubcategory).AsEnumerable(), new XmlMediaTypeFormatter()); // change the formatters accordingly

            MemoryStream ms = new MemoryStream();

            // This line would cause the formatter's WriteToStream method to be invoked.
            // Any exceptions during WriteToStream would be thrown as part of this call
            responseContent.CopyToAsync(ms).Wait();
Kiran Challa
quelle
Vielen Dank. Das Hinzufügen zu meiner Aktion und das Festlegen eines Haltepunkts war die einzige Möglichkeit, die Ausnahme zu erkennen. Prost!
Asgeo1
2
Also ist es nicht für Selfhost behoben?
JefClaes
2
Post RC ist noch nicht veröffentlicht, oder? Es sei denn, Sie bauen aus Quellen?
JefClaes
59

Sie können versuchen, Folgendes hinzuzufügen:

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = 
    IncludeErrorDetailPolicy.Always;

zu Ihrem Application_Start()in der Global.asax. Diese Lösung funktioniert für viele der häufigsten Fehler.

Wenn Sie jedoch keine zufriedenstellenden Informationen erhalten, sollten Sie einen Ausnahmefilter schreiben und global registrieren.

Dieser Artikel soll Ihnen den Einstieg erleichtern. Der Kern dessen, was Sie brauchen, ist das Schreiben und Registrieren von etwas wie:

public class NotImplExceptionFilter : ExceptionFilterAttribute {
  public override void OnException(HttpActionExecutedContext context) {
     if (context.Exception is NotImplementedException) {
       context.Response = new HttpResponseMessage(HttpStatusCode.NotImplemented);
    }
  }
}
Stever B.
quelle
1
@EBarr Das habe ich schon versucht, bevor ich meine Frage gestellt habe. Ich habe Ihre Antwort hier gesehen stackoverflow.com/questions/10487943/… Es funktioniert irgendwie nicht. Mein Fehler 500 hat noch einen leeren Körper. Ich habe in Chrome die Registerkarte "Netzwerk" verwendet, um Antworten vom Server anzuzeigen.
Oddy
1
@Oddy - Wenn das oben genannte fehlschlägt, habe ich keine gute Möglichkeit zum Debuggen gefunden. Wenn der Fehler auftritt, nachdem Ihre Aktion zurückgegeben wurde, sehe ich einige Möglichkeiten - 1) die oben genannten, 2) Ihre Rückgabe ist eine IEnumerable, die eine fehlerhafte Abfrage ausführt. Versuchen Sie a .ToList(), die Abfrage zu überprüfen. 3) Deaktivieren oder debuggen Sie die 2. Hälfte aller Nachrichtenhandler ( ContinueWith()Abschnitt) oder 3) Die Ausgabeformatierung ist fehlerhaft (json oder xml). Verwenden Sie also fiddler / was auch immer, um nach einem alternativen Format zu fragen.
EBarr
2
@SteverB - nicht sicher, warum dich jemand herabgestimmt hat. Diese Antwort funktioniert in vielen Szenarien.
EBarr
1
Ich habe genau das gleiche Problem; Ich habe versucht, einen benutzerdefinierten Ausnahmefilter, eine globale Konfiguration usw. zu verwenden. Dies geschieht am Ende der Pipeline nach allen Ereignissen. Nur ein Server 500 sonst nichts. Sogar die Site wurde auf IIS 7.5 verschoben und die IIS-Ablaufverfolgung aktiviert - alles, was getan wurde, war die 500 zu bestätigen, nichts anderes, kein Stapel, nichts, um mich über den Fehler zu informieren. 100% Repro auch in kleiner Lösung.
Shawn Cicoria
1
@EBarr meine Beschreibung des Problems ist kurz und auf den Punkt. Wie Sie sehen, hat niemand darum gebeten, weitere Details hinzuzufügen. Und ich kann immer noch keine Details für den Serverfehler 500 erhalten, der vom Server unter Verwendung des oben genannten Ansatzes zurückgegeben wurde.
Oddy
4

Ich bin auf dasselbe Problem gestoßen. Ich fand Kiran Challas Antwort hilfreich, um die eigentliche Ausnahme außerhalb meiner Aktion zu werfen.

Um mein Problem zu lösen, habe ich die ProxyCreationEnabled-Eigenschaft meines Kontexts auf false gesetzt und bin einen Schritt weiter gegangen .

In meinem Szenario war meine nächste Ausnahme auf einen Zirkelverweis in meinen Modellen zurückzuführen. Nach dem Aufräumen war die Phantom 500-Antwort weg. Viel Glück, wenn Sie dies noch nicht gelöst haben!

Blocka
quelle
3

Dies kann mit einem Zirkelverweis zusammenhängen.

http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#handling_circular_object_references

Fügen Sie der Application_Start-Methode in der Datei Global.asax den folgenden Code hinzu:

 var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
 json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.All;
Simcha Khabinsky
quelle
3

Eine täuschend einfache Routing-Schwäche verursachte in meinem Fall dieses Problem: In meinem Api-Controller befand sich ein weiterer HttpPost mit derselben Signatur (nicht Name). Das Standardrouting löste die Namensunterschiede nicht auf, und der ServiceError 500 war die Antwort, die er gab, bevor eine der API-Funktionen erreicht wurde. Lösung: Ändern Sie das Standardrouting oder Ihre Signaturen und versuchen Sie es erneut.

Hier ist meine RouteConfig.cs, die für die Standardnutzung von WebApi2 recht gut funktioniert:

    public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        // Default is required in any case.
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}
GGleGrand
quelle
Das scheint verrückt zu sein, da dachte ich, es sollte einfach abholen. Ich bin mir nicht sicher, ob ich das jemals gefunden hätte. Dies muss ein echter Schmerz für jeden sein, der viele Methoden hat, die ein einzelnes JSON-Objekt usw. übergeben.
Neil P
Angenommen, es ist vielleicht eine Funktion, die kein Fehler ist ... sie hat uns auch verrückt gemacht :-) ... oder wird in WebApi3 behoben.
GGleGrand
2

Ich hatte das Problem in RC, als ich die Abfrageparameter nicht in der richtigen Reihenfolge angab. Wenn Sie beispielsweise angeben $skip=0, wird 500 angezeigt, wenn Sie jedoch $orderby=xxx&skip=0keinen Fehler angeben .

Jimzy
quelle
2

Dieses Szenario wurde aus folgenden Gründen verursacht

  1. Das Problem trat aufgrund einer fehlerhaften Web.config auf. (Mehrere configSections)

  2. Anstatt einen Roslyn- Ordner im Bin- Ordner zu erstellen , habe ich ihn im Stammverzeichnis erstellen lassen . (Bereitstellungsort.)

Der beste Weg, dies zu diagnostizieren, bestand darin, eine einfache HTML-Seite am Anwendungsort abzulegen und zu versuchen, sie zu durchsuchen. 500 Die Fehlerbeschreibung wird auf dieser HTML-Seite angezeigt.

Und vergessen Sie auch nicht hinzuzufügen

<customErrors mode="Off"></customErrors>

zu Web.config

Schein
quelle
1

Normalerweise verwende ich Global.asax, um alle Fehler abzufangen. Hier ist ein Code-Snip, den Sie verwenden können

public void Application_Error(object sender, EventArgs e)
{
  Exception exc = Server.GetLastError();
  MvcApplication mvcApplication = sender as MvcApplication;
  HttpRequest request = null;
  if (mvcApplication != null) request = mvcApplication.Request;
}
Anders
quelle
1

Ich hatte das gleiche Problem, aber die Quelle war etwas anders: Ich habe die CORSRichtlinie falsch eingestellt und das gibt mir 500 Internal server error, aber da CORSes nicht funktionierte, wurde der Access-Control-Allow-OriginHeader nicht als Antwort angezeigt und der Browser kann die tatsächliche Antwort nicht lesen

Ich habe es mit der Option ChromeDevTools gelöst, mit Copy as cURLder ich die Antwort sehen und die Fehlerquelle verstehen kann

Saito
quelle
0

Fredrik Normén hat einen großartigen Blog-Beitrag mit dem Titel ASP.NET Web API Exception Handling zu diesem Thema geschrieben. Seine Lösung verwendet benutzerdefinierte Ausnahmeklassen und ein Ausnahmefilterattribut, das auf alle ApiControllerAktionsmethoden angewendet werden kann.

Marius Schulz
quelle