2012-11-27 21 views
14

Uso l'hub SignalR nella mia applicazione MVC4. Ho aggiunto ELMAH per gestire tutti gli errori. il problema è che gli errori che si verificano nell'Hub non vengono registrati in ELMAH axd. C'è un modo per configurarlo?Come configurare ELMAH con SignalR

risposta

9

È necessario aggiungere un HubPipelineModule e assicurarsi inoltre di impostare un NomeApplicazione nell'elemento errorLog, altrimenti Elmah non sarà in grado di registrare un errore, in quanto non avrà un HttpContext o un NomeApp per accedere a .

<errorLog type="Elmah.SqlErrorLog, Elmah" applicationName="MyAppName" connectionStringName="myConnString" /> 

Il HubPipelineModule code I've used è la seguente:

public class ElmahPipelineModule : HubPipelineModule 
{ 
    private static bool RaiseErrorSignal(Exception e) 
    { 
     var context = HttpContext.Current; 
     if (context == null) 
      return false; 
     var signal = ErrorSignal.FromContext(context); 
     if (signal == null) 
      return false; 
     signal.Raise(e, context); 
     return true; 
    } 

    private static void LogException(Exception e, IHubIncomingInvokerContext invokerContext) 
    { 
     var context = HttpContext.Current; 
     ErrorLog el = ErrorLog.GetDefault(context); 
     el.Log(new Error(e)); 
    } 

    protected override void OnIncomingError(Exception ex, IHubIncomingInvokerContext context) 
    { 
     var exception = ex; 
     if (ex is TargetInvocationException) 
     { 
      exception = ex.InnerException; 
     } 
     else if (ex is AggregateException) 
     { 
      exception = ex.InnerException; 
     } 

     if (!RaiseErrorSignal(exception)) 
      LogException(exception, context); 
    } 
} 

Assicurati di aggiungere il modulo alla pipeline hub:

GlobalHost.HubPipeline.AddModule(new ElmahPipelineModule()); 

EDIT

SignalR 2+

Ho notato che nessuna delle mie eccezioni SignalR è stata registrata in un progetto recente su cui ho lavorato e ho scoperto che viene generata un'eccezione ArgumentNullException quando si tenta di ottenere ErrorSignal dal contesto corrente. Il seguente metodo tratta correttamente questa eccezione in modo che gli errori SignalR vengano registrati nuovamente.

private static bool RaiseErrorSignal(Exception e) 
{ 
    var context = HttpContext.Current; 
    if (context == null) 
     return false; 

    try 
    { 
     var signal = ErrorSignal.FromCurrentContext(); 
     if (signal == null) 
      return false; 
     signal.Raise(e, context); 
     return true; 
    } 
    catch (ArgumentNullException) 
    { 
     return false; 
    } 
} 
+1

Per chiunque altro si blocchi nell'ultimo passaggio, aggiungere l'ultima riga alla classe RegisterHubs. Ad esempio: 'public static void Start() {RouteTable.Routes.MapHubs(); GlobalHost.HubPipeline.AddModule (new Shopperscape.Web.API.ElmahPipelineModule()); } ' – Chris

+0

@Chris Funziona per SignalR 1.x? –

+1

@Giles - questo codice è per SignalR 1 – damienc88