Я использую концентратор SignalR в своем приложении MVC4. Я добавил ELMAH для обработки всех ошибок. проблема в том, что ошибки, которые происходят в концентраторе, не регистрируются в ELMAH axd. Есть ли способ настроить его?
Как настроить ELMAH с помощью SignalR
Ответ 1
Вы должны добавить HubPipelineModule
, а также убедиться, что вы установили имя приложения в свой элемент errorLog. В противном случае Elmah не сможет зарегистрировать ошибку, так как у нее не будет HttpContext или AppName для входа в журнал к.
<errorLog type="Elmah.SqlErrorLog, Elmah" applicationName="MyAppName" connectionStringName="myConnString" />
Код HubPipelineModule, который я использовал, выглядит следующим образом:
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);
}
}
Убедитесь, что модуль подключен к конвейеру:
GlobalHost.HubPipeline.AddModule(new ElmahPipelineModule());
EDIT
SignalR 2 +
Я заметил, что ни один из моих исключений SignalR не регистрировался в недавнем проекте, над которым я работал, и обнаружил, что при попытке получить ErrorSignal из текущего контекста создается ArgumentNullException. Следующий метод правильно справляется с этим исключением, так что ошибки SignalR регистрируются еще раз.
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;
}
}