Hintergrund
Ich entwickle eine API-Service-Schicht für einen Client und wurde aufgefordert, alle Fehler global abzufangen und zu protokollieren.
Während also so etwas wie ein unbekannter Endpunkt (oder eine unbekannte Aktion) einfach zu handhaben ist, verwenden Sie ELMAH oder fügen Sie Folgendes hinzu Global.asax
:
protected void Application_Error()
{
Exception unhandledException = Server.GetLastError();
//do more stuff
}
. . Nicht behandelte Fehler, die nicht mit dem Routing zusammenhängen, werden nicht protokolliert. Beispielsweise:
public class ReportController : ApiController
{
public int test()
{
var foo = Convert.ToInt32("a");//Will throw error but isn't logged!!
return foo;
}
}
Ich habe auch versucht, das [HandleError]
Attribut global festzulegen, indem ich diesen Filter registriert habe:
filters.Add(new HandleErrorAttribute());
Das protokolliert aber auch nicht alle Fehler.
Problem / Frage
Wie fange ich Fehler ab, wie sie durch den /test
obigen Aufruf generiert wurden, damit ich sie protokollieren kann? Es scheint, dass diese Antwort offensichtlich sein sollte, aber ich habe alles versucht, was mir bisher einfällt.
Im Idealfall möchte ich der Fehlerprotokollierung einige Dinge hinzufügen, z. B. die IP-Adresse des anfordernden Benutzers, Datum, Uhrzeit usw. Ich möchte auch in der Lage sein, dem Support-Personal automatisch eine E-Mail zu senden, wenn ein Fehler auftritt. All dies kann ich tun, wenn ich diese Fehler nur abfangen kann, wenn sie auftreten!
AUFGELÖST!
Dank Darin Dimitrov, dessen Antwort ich akzeptierte, habe ich das herausgefunden. WebAPI behandelt Fehler nicht wie ein normaler MVC-Controller.
Folgendes hat funktioniert:
1) Fügen Sie Ihrem Namespace einen benutzerdefinierten Filter hinzu:
public class ExceptionHandlingAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
if (context.Exception is BusinessException)
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent(context.Exception.Message),
ReasonPhrase = "Exception"
});
}
//Log Critical errors
Debug.WriteLine(context.Exception);
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent("An error occurred, please try again or contact the administrator."),
ReasonPhrase = "Critical Exception"
});
}
}
2) Registrieren Sie nun den Filter global in der WebApiConfig- Klasse:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{action}/{id}", new { id = RouteParameter.Optional });
config.Filters.Add(new ExceptionHandlingAttribute());
}
}
ODER Sie können die Registrierung überspringen und einfach einen einzelnen Controller mit dem [ExceptionHandling]
Attribut dekorieren .