2009-09-23 14 views
14

Voglio usare Application_Error con il mio progetto MVC, ma non riesco a farlo funzionare. Aggiungo il seguente al mio file Global.asax: (. La Sessione è solo per le prove Im che va utilizzare un database per errore di log, se ottengo questo al lavoro.)Come utilizzo Application_Error in ASP.NET MVC?

protected void Application_Error(object sender, EventArgs e) 
    { 
     Exception objErr = Server.GetLastError().GetBaseException(); 
     Session["Test"] = "Message:" + objErr.Message.ToString(); 
    } 

poi cerco di lanciare un eccezione dal mio HomeController e dalla mia vista Home/Index, ma attiva solo Debug.

public ActionResult Index() 
    { 
     ViewData["Message"] = "Welcome to ASP.NET MVC!"; 
     throw (new Exception()); 
     return View(); 
    } 

Nel mio file Webconfig ho creato una pagina defaulterror ma non reindirizza alla vista:

<customErrors defaultRedirect="Home/Error"> 
     <error statusCode="403" redirect="NoAccess.htm" /> 
     <error statusCode="404" redirect="FileNotFound.htm" /> 
    </customErrors> 

risposta

14

Quindi, innanzitutto, ricordare che la gestione globale degli errori dovrebbe essere l'ultima risorsa e che le classi controller hanno un metodo di errore specifico per gli errori;

protected virtual bool OnError(string actionName, 
    System.Reflection.MethodInfo methodInfo, Exception exception) 

All'interno di questo è possibile reindirizzare alla visualizzazione di errore condiviso standard;

protected override bool OnError(string actionName, 
    System.Reflection.MethodInfo methodInfo, Exception exception) 
{ 
    RenderView("Error", exception); 
    return false; 
} 

Il problema che avete in errore di applicazione globale è che non ha alcun concetto di vista o controller, quindi se si desidera reindirizzare in là, allora è necessario utilizzare un URL noto

protected void Application_Error(object sender, EventArgs e) 
{ 
    Exception exception = Server.GetLastError(); 
    System.Diagnostics.Debug.WriteLine(exception); 
    Response.Redirect("/Home/Error"); 
} 

ma non è necessario farlo. Se imposti la pagina di errore predefinita nel web.config, allora non è necessario che reindirizzano

<customErrors defaultRedirect="Home/Error" /> 

Tuttavia, a meno che non hai aggiunto un errore da casa il controller che non esiste, in modo da aggiungere il seguente al controller di casa

public ActionResult Error() 
{ 
    return View(); 
} 

Quindi (se sei sensibile) inseriresti il ​​codice di gestione degli errori nel metodo Error(), poiché è lì che finiranno tutti gli errori non gestiti.

public ActionResult Error() 
{ 
    Exception exception = Server.GetLastError(); 
    System.Diagnostics.Debug.WriteLine(exception); 
    return View(); 
} 

Infine, ricorda che per impostazione predefinita non vengono visualizzati errori personalizzati se ci si connette a localhost! Quindi è necessario modificare tale comportamento

<customErrors mode="On" defaultRedirect="/Home/Error" /> 
+1

Ho un problema con la soluzione. CustomErrors reindirizza direttamente alla vista Home/Errori senza attivare il controller. Non sapevo cosa fosse possibile, ma quando ho messo un punto di debug nel metodo Error Action il debug non viene mai chiamato. La visualizzazione degli errori viene visualizzata sullo schermo, ma l'url è sempre uguale all'URL che ha attivato l'errore. Ad esempio, se faccio scattare un errore in/Home/Lavoro, otterrò la vista errore ma l'URL è ancora/Home/Lavoro – Poku

+18

Ehi @blowdart: messaggio per gentile concessione di un nuovo utente che non può commentare: questa risposta è piatta sbagliato. Il problema è che chiamare Server.GetLastError() dalla classe controller non funziona se si utilizza web.config per reindirizzare a un'azione del controller predefinita. ASP avvia una nuova richiesta HTTP al controller degli errori, che cancella le variabili Server, perdendo le informazioni sulle eccezioni. –

+3

risposta errata ..... ecco un buon articolo sul perché è necessario utilizzare entrambi http://www.prideparrot.com/blog/archive/2012/5/exception_handling_in_asp_net_mvc –

1
  • Avete un sessione istituito, in primo luogo? Se l'errore viene attivato da un IHttpHandler non contrassegnato con IRequiresSessionState, l'accesso a Session avrà esito negativo.
  • Che cosa stai facendo con Session["Test"]? Sei sicuro che il tuo codice non funzioni? Potresti provare un File.Open e semplicemente emettere un testo (ad esempio, l'ora corrente) a C:\my-log.txt, che ha una probabilità leggermente maggiore di riuscire rispetto all'utilizzo di Session.
  • GetBaseException non è utile in questo caso (né generalmente per la registrazione) per quanto posso dire.
  • Message è di tipo string - la chiamata .ToString() non è necessaria. In generale, consigliamo vivamente di di evitareToString() dove possibile - se lo stai utilizzando perché non sei sicuro del tipo di oggetto, dovrebbe essere una bandiera rossa; fare un end-run attorno al sistema di tipi può nascondere bug sottili (ad esempio, DBNull.Value.ToString() == ""). Per i GUI i tipi predefiniti forniscono un sovraccarico .ToString(IFormatProvider) che è sensibile alla cultura ed evita problemi di portabilità. Poiché anche questo sovraccarico non è presente su object, è anche un modo per evitare le chiamate da .ToString con caratteri debolmente tipizzati.
Problemi correlati