Erreurs de journalisation ASP.NET MVC
j'utilise actuellement log4net dans mon ASP.NET MVC application to log exceptions. La façon dont je fais ça, c'est d'avoir tous mes contrôleurs hérités d'une classe de BaseController. Dans L'événement OnActionExecuting de BaseController, j'enregistre toutes les exceptions qui ont pu se produire:
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);
}
}
cela fonctionne très bien si une exception s'est produite pendant une intervention du contrôleur.
comme pour les erreurs 404, j'ai une erreur personnalisée configurée dans mon web.config comme so:
<customErrors mode="On">
<error statusCode="404" redirect="~/page-not-found"/>
</customErrors>
et dans l'action du contrôleur qui gère l'url "page-not-found", j'enregistre l'url originale demandée:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult PageNotFound()
{
log.Warn("404 page not found - " + Utils.SafeString(Request.QueryString["aspxerrorpath"]));
return View();
}
et ça marche aussi.
le problème que j'ai est comment enregistrer les erreurs qui sont sur le .aspx pages eux-mêmes. Disons que j'ai une erreur de compilation sur une des pages ou un code inline qui va jeter une exception:
<% ThisIsNotAValidFunction(); %>
<% throw new Exception("help!"); %>
il semble que L'attribut HandleError dévie correctement ceci de mon erreur.la page aspx dans le dossier partagé, mais elle n'est certainement pas capturée par la méthode OnActionExecuted de mon BaseController. Je pensais que je pourrais peut-être mettre le code de journalisation sur L'erreur.aspx page elle-même, mais je ne sais pas comment récupérer l'information d'erreur à ce niveau.
6 réponses
j'envisagerais de simplifier votre application web en branchant Elmah .
vous ajoutez L'assemblage D'Elmah à votre projet puis configurez votre web.config. Il enregistrera alors les exceptions créées au niveau du controller ou de la page. Il peut être configuré pour se connecter à différents endroits (comme SQL Server, Email etc). Il fournit également un frontend web, de sorte que vous pouvez parcourir le journal des exceptions.
C'est le premier ce que j'ajoute à tout asp.net MVC app I create.
j'utilise encore log4net, mais j'ai tendance à l'utiliser pour la journalisation de debug/info, et je laisse toutes les exceptions à Elmah.
vous pouvez également trouver plus d'informations dans la question comment enregistrez-vous les erreurs (Exceptions) dans votre ASP.NET applis? .
vous pouvez vous connecter à L'événement OnError dans le Global.asax.
quelque chose comme ça:
/// <summary>
/// Handles the Error event of the Application control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
protected void Application_Error(object sender, EventArgs e)
{
if (Server != null)
{
Exception ex = Server.GetLastError();
if (Response.StatusCode != 404 )
{
Logging.Error("Caught in Global.asax", ex);
}
}
}
MVC3
Créer L'attribut qui hérite de HandleErrorInfoAttribute et inclut votre choix de journalisation
public class ErrorLoggerAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
LogError(filterContext);
base.OnException(filterContext);
}
public void LogError(ExceptionContext filterContext)
{
// You could use any logging approach here
StringBuilder builder = new StringBuilder();
builder
.AppendLine("----------")
.AppendLine(DateTime.Now.ToString())
.AppendFormat("Source:\t{0}", filterContext.Exception.Source)
.AppendLine()
.AppendFormat("Target:\t{0}", filterContext.Exception.TargetSite)
.AppendLine()
.AppendFormat("Type:\t{0}", filterContext.Exception.GetType().Name)
.AppendLine()
.AppendFormat("Message:\t{0}", filterContext.Exception.Message)
.AppendLine()
.AppendFormat("Stack:\t{0}", filterContext.Exception.StackTrace)
.AppendLine();
string filePath = filterContext.HttpContext.Server.MapPath("~/App_Data/Error.log");
using(StreamWriter writer = File.AppendText(filePath))
{
writer.Write(builder.ToString());
writer.Flush();
}
}
attribut de Place dans Global.asax RegisterGlobalFilters
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
// filters.Add(new HandleErrorAttribute());
filters.Add(new ErrorLoggerAttribute());
}
L'Erreur.aspx view est défini comme suit:
namespace MvcApplication1.Views.Shared
{
public partial class Error : ViewPage<HandleErrorInfo>
{
}
}
le HandleErrorInfo a trois propriétés: string ActionName string ControllerName Exception Exception
vous devriez être en mesure d'accéder à HandleErrorInfo et donc L'Exception dans la vue.
vous pouvez essayer d'examiner HttpContext.L'erreur, mais je ne suis pas sûr sur ce point.