Wir verwenden das ausgezeichnete ELMAH um mit unbehandelten Ausnahmen in einer ASP.NET 3.5-Webanwendung umzugehen. Dies funktioniert sehr gut für die gesamte Website, mit Ausnahme der WCF-Dienste, die über die REST-Funktionen genutzt werden. Wenn innerhalb der Operationsmethoden eine Ausnahme auftritt, die nicht vom Anwendungscode behandelt wird, behandelt WCF diese auf verschiedene Weise, abhängig von den Dienstverträgen und Konfigurationseinstellungen. Dies bedeutet, dass die Ausnahme nicht zum Auslösen des ASP.NET HttpApplication.Error-Ereignisses führt, das ELMAH verwendet. Die beiden mir bekannten Lösungen für dieses Problem sind:
- Wickeln Sie alle Methodenaufrufe in ein try { } catch(Exception ex) { Elmah.ErrorSignal.FromCurrentContext().Raise(ex); throw; } ein, um Elmah explizit innerhalb des catch-Blocks aufzurufen.
- Utilice IErrorHandler wie beschrieben in Will Hughes' Blog-Beitrag Das Zusammenspiel von WCF und ELMAH um den Aufruf von ELMAH in einen separaten ErrorHandler auszulagern.
Die erste Option ist extrem einfach, aber nicht gerade DRY . Bei der zweiten Option müssen Sie nur jeden Dienst mit dem benutzerdefinierten Attribut dekorieren, nachdem Sie das Attribut und den ErrorHandler implementiert haben. Ich habe dies auf der Grundlage von Will's funktionieren, aber ich möchte überprüfen, ob es sich um die richtiger Ansatz bevor Sie den Code veröffentlichen.
Gibt es einen besseren Weg, den ich übersehen habe?
Die MSDN-Dokumentation für IErrorHandler sagt, dass die HandleError Methode ist der richtige Ort für die Protokollierung, aber ELMAH greift auf den HttpContext.Current. Anwendungsinstanz die in dieser Methode null ist, obwohl HttpContext.Current verfügbar ist. Der Aufruf von Elmah innerhalb der ProvideFault-Methode ist ein Workaround, da ApplicationInstance festgelegt wird, aber dies entspricht nicht der in der API-Dokumentation beschriebenen Absicht. Übersehe ich hier etwas? In der Dokumentation heißt es, dass Sie sich nicht darauf verlassen sollten, dass die HandleError-Methode auf dem Operationsthread aufgerufen wird, weshalb ApplicationInstance in diesem Bereich möglicherweise null ist.