Obecnie używam log4net w mojej aplikacji ASP.NET MVC do rejestrowania wyjątków. Sposób, w jaki to robię, polega na tym, że wszystkie moje kontrolery dziedziczą z klasy BaseController. W zdarzeniu OnActionExecuting BaseControllera rejestruję wszelkie wyjątki, które mogły wystąpić:
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
// Log any exceptions
ILog log = LogManager.GetLogger(filterContext.Controller.GetType());
if (filterContext.Exception != null)
{
log.Error("Unhandled exception: " + filterContext.Exception.Message +
". Stack trace: " + filterContext.Exception.StackTrace,
filterContext.Exception);
}
}
Działa to świetnie, jeśli wystąpił nieobsługiwany wyjątek podczas akcji kontrolera.
Jeśli chodzi o błędy 404, mam niestandardowy błąd ustawiony w moim pliku web.config w następujący sposób:
<customErrors mode="On">
<error statusCode="404" redirect="~/page-not-found"/>
</customErrors>
W akcji kontrolera, która obsługuje adres URL „nie znaleziono strony”, rejestruję żądany pierwotny adres URL:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult PageNotFound()
{
log.Warn("404 page not found - " + Utils.SafeString(Request.QueryString["aspxerrorpath"]));
return View();
}
I to też działa.
Problem, który mam, polega na tym, jak rejestrować błędy na samych stronach .aspx. Załóżmy, że mam błąd kompilacji na jednej ze stron lub jakiś wbudowany kod, który zgłosi wyjątek:
<% ThisIsNotAValidFunction(); %>
<% throw new Exception("help!"); %>
Wygląda na to, że atrybut HandleError prawidłowo przekierowuje to na moją stronę Error.aspx w folderze udostępnionym, ale zdecydowanie nie jest przechwytywany przez metodę OnActionExecuted mojego BaseControllera. Myślałem, że mógłbym umieścić kod logowania na samej stronie Error.aspx, ale nie jestem pewien, jak pobrać informacje o błędzie na tym poziomie.