2013-04-29 24 views
5

Nell'interesse di mostrare sempre una pagina di errore "amichevole" agli utenti quando visitano un sito che ho trovato nella pagina Global.asax, la maggior parte degli errori è gestita da filtri che sembrano essere i preferiti metodo. Per la maggior parte, questo funziona bene. Tuttavia, durante Application_Start, l'evento Application_Error (comprensibilmente) non viene attivato.Come posso gestire gli errori in Global.asax Application_Start?

Il mio evento Application_Start contiene un codice di inizializzazione che dipende da una chiamata di servizio, quindi un punto di errore facilmente definito è se il servizio non è disponibile per qualsiasi motivo. L'unico modo che ho trovato per aggirare questo è quello di fare quanto segue.

private static Exception StartUpException; 
    protected void Application_Start() 
    { 
     AreaRegistration.RegisterAllAreas(); 
     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
     RouteConfig.RegisterRoutes(RouteTable.Routes); 
     Initialise();  
    } 

    private void Initialise() 
    { 
     StartUpException = null; 
     try 
     { 
      Bootstrapper.Initialise(); 
     } 
     catch (Exception ex) 
     { 
      StartUpException = ex; 
     } 
    } 

allora ho il seguente codice nel Application_BeginRequest

protected void Application_BeginRequest(object sender, EventArgs e) 
    { 
     if (StartUpException != null) 
     { 
      HandleErrorAndRedirect(StartUpException); 
      HttpRuntime.UnloadAppDomain(); 
      Response.End(); 
     } 
    } 

Questo funziona, ma sembra un po 'di hack. Inoltre, non sono sicuro delle conseguenze derivanti dal chiamare UnloadAppDomain o di cosa accadrebbe se arrivassero più richieste. C'è un modo migliore per gestirlo?

+0

Does 'GlobalFilters.Filters' include 'HandleError'? Se è così, quello sta prendendo tutti gli errori. – alexn

+0

No, l'ho rimosso. – DJG

+0

Scusa il mio modo di dire, ma sicuramente il fatto che il tuo application_start dipenda da un servizio è un po 'una mossa sbagliata [IMHO]? Non c'è modo che questo possa essere spostato altrove? L'avvio dell'app è un po 'pesante! Mi aspetto anche se fallisce, e poi scarica, che la prossima richiesta di entrare sia in attesa di un app_start da completare e quindi di prelevare il thread, o chiamare un altro App_Start che poi fallirebbe. –

risposta

3

Abbiamo problemi con il bootstrap in App_Start perché HttpContext non è stato impostato e alcune delle classi bootstapped lo hanno richiesto; comunque questo dovrebbe funzionare anche per il tuo caso:

public class MvcApplication : System.Web.HttpApplication {  
    protected void Application_BeginRequest() { 
     var context = this.Context; 
     FirstTimeInitializer.Init(context); 
    } 

    private static class FirstTimeInitializer { 
     private static bool s_IsInitialized = false; 
     private static Object s_SyncRoot = new Object(); 

     public static void Init(HttpContext context) { 
      if (s_IsInitialized) { 
       return; 
      } 

      lock (s_SyncRoot) { 
       if (s_IsInitialized) { 
        return; 
       } 

       // bootstrap 

       s_IsInitialized = true; 
      } 
     } 
    } 
} 
Problemi correlati