2010-05-21 3 views
6

J'utilise ELMAH pour consigner des exceptions non gérées dans une application ASP.NET Webforms. La journalisation fonctionne bien.Problème lors de la transmission de l'ID de journal ELMAH à la page d'erreur personnalisée dans ASP.NET

Je souhaite transmettre l'ID du journal des erreurs ELMAH à une page d'erreur personnalisée qui permettra à l'utilisateur d'envoyer un message électronique à l'administrateur à propos de l'erreur. J'ai suivi le conseil de this answer. Voici mon global.asax code:

void ErrorLog_Logged(object sender, ErrorLoggedEventArgs args) 
{   
    Session[StateKeys.ElmahLogId] = args.Entry.Id; 

    // this doesn't work either: 
    // HttpContext.Current.Items[StateKeys.ElmahLogId] = args.Entry.Id; 
} 

Mais, sur la page d'erreur personnalisée, la référence variable de session et HttpContext.Current.Items me donnent une exception NullReference. Comment puis-je transmettre l'identifiant à ma page d'erreur personnalisée?

Répondre

7

Cela fonctionne pour moi:

void ErrorLog_Logged(object sender, ErrorLoggedEventArgs args) 
{ 
    if (args.Entry.Error.Exception is HandledElmahException) 
     return; 

    var config = WebConfigurationManager.OpenWebConfiguration("~"); 
    var customErrorsSection = (CustomErrorsSection)config.GetSection("system.web/customErrors");   

    if (customErrorsSection != null) 
    { 
     switch (customErrorsSection.Mode) 
     { 
      case CustomErrorsMode.Off: 
       break; 
      case CustomErrorsMode.On: 
       FriendlyErrorTransfer(args.Entry.Id, customErrorsSection.DefaultRedirect); 
       break; 
      case CustomErrorsMode.RemoteOnly: 
       if (!HttpContext.Current.Request.IsLocal) 
        FriendlyErrorTransfer(args.Entry.Id, customErrorsSection.DefaultRedirect); 
       break; 
      default: 
       break; 
     } 
    }   
} 

void FriendlyErrorTransfer(string emlahId, string url) 
{ 
    Server.Transfer(String.Format("{0}?id={1}", url, Server.UrlEncode(emlahId))); 
} 
+2

Où 'HandledElmahException' est une classe personnalisée comme décrit dans votre réponse [ici] (http://stackoverflow.com/a/2906221/39396) –

+4

Avez-vous déjà reçu une erreur" Exécution d'une requête enfant ... "avec 'Server.Transfer'? –

2

Impossible de commenter la solution de Ronnie. J'ai eu cela en place pendant un certain temps, mais il rompt le processus standard de flux d'erreur et provoque ErrorLog_Logged de transférer toujours, même lorsque vous appelez

Elmah.ErrorSignal.FromCurrentContext().Raise(ex);

Ceci est un problème si vous voulez encore enregistrer une erreur à partir d'un instruction catch, par exemple vous avez une solution de contournement pour une erreur, mais vous voulez enregistrer l'erreur pour effectuer une correction appropriée, ce qui peut être très utile sur les problèmes difficiles à répliquer.

j'ai pu corriger cela en utilisant la modification suivante:

//if (customErrorsSection != null)  
if (customErrorsSection != null && this.Context.Error != null) 

Ce respecte l'erreur typique de manipulation correctement, comme context.Error sera nulle dans les cas où vous soulevez l'exception explicitement Elmah, mais n'est pas nul en cas de traitement d'erreur par défaut (pas via un catch ou si attrapé et relancé). Cela provoque la réponse de Ronnie à une réponse similaire à la logique de gestion des erreurs .Net.

+0

J'ai arrêté d'utiliser Elmah il y a un certain temps. Il est plus facile de consigner vos erreurs vous-même. –

+0

Ouais, je ne sais pas si je redescendrais la route d'Elmah non plus. C'est pratique car il fait une belle présentation ou trace la pile sans beaucoup de travail, mais il me laisse généralement envie de l'étendre, de changer la structure des données et d'autres choses qui ne valent généralement pas l'effort nécessaire. – user2701750

+0

Obtenir une trace de pile ne devient pas vraiment plus facile que d'appeler exception.ToString() ... Inclut le type d'exception, le message et la pile d'appels et les récursifs via les inners. –

Questions connexes