3

Выполнение моего регистратора ошибок [IExceptionLogger][1] вызывается дважды, когда исключение выбрасывается из действия контроллера.ASP.NET Web API IExceptionLogger, вызываемый дважды

context.RequestContext.Configuration.Services.GetServices(typeof(IExceptionLogger)) 

это возвращает одну запись, поэтому я уверен, что зарегистрирован только один экземпляр регистратора. Я не хочу, чтобы мои необработанные исключения записывались дважды, и я не думаю, что это ожидаемое поведение по умолчанию. Как устранить причину этого?

Если я установил точку останова в методе LogAsync(), столбец вызова показывает [External Code] по обоим вызовам.

[RoutePrefix("test")] 
public class MyController : ApiController 
{ 
    [HttpGet, AllowAnonymous] 
    [Route("test")] 
    public string GetTest() 
    { 
     throw new InvalidOperationException("Shit happens"); 
    } 
} 

Регистратор вводится так:

config.Services.Add(typeof(IExceptionLogger), new WebApiExceptionLogger()); 

public class WebApiExceptionLogger : IExceptionLogger 
{ 
    private readonly ILoggingService loggingService; 

    public WebApiExceptionLogger() 
    { 
     this.loggingService = ServiceContainer.Factory.Resolve<ILoggingService>(); 
    } 

    public Task LogAsync(ExceptionLoggerContext context, CancellationToken cancellationToken) 
    { 
     this.loggingService.Log(LogLevel.Error, this.GetType().Name, context.Exception, "Ship has just happened"); 
     return Task.FromResult(true); 
    } 
} 
+0

Показать регистрационный код? Можно ли просто выбросить два исключения? – MartinM

ответ

4

Try изменения WebApiExceptionLogger так, что она наследуется от ExceptionLogger вместо. ExceptionLogger реализует настраиваемый метод «ShouldLog», который подавляет повторяющиеся вызовы. (вы не должны переопределять этот метод, если вы не можете предоставить аналогичную логику). Это решило проблему для меня.

Я думаю, что это поведение связано с тем, что WebApi2 дважды вызывает Log/LogAsync для каждого запроса, когда Исключение произошло из разных местоположений в конвейере. Если у вас нет логики для этого, вы получите дубликаты журнальных вызовов.

0

Примечание стороны о том, когда вы хотите, чтобы решить ваши глобальные обработчик исключений с autofac здесь является то, что вы можете сделать:

1) Убедитесь, что метод типа autofac регистрации называется первым. Там вы, как правило, сделать что-то вроде этого:

 builder.RegisterType<AppExceptionLogger>().AsSelf().AsImplementedInterfaces(); 
     builder.RegisterType<AppExceptionHandler>().AsSelf().AsImplementedInterfaces(); 

2) Добавьте следующие строки в WebApiConfig.Register (HttpConfiguration конфигурации) или аналогичный вызов у ​​вас есть:

 // Inject our exception logger and handler (get one from DR/Autofac) 
     config.Services.Replace(typeof(IExceptionHandler), config.DependencyResolver.GetService(typeof(AppExceptionHandler))); 
     config.Services.Replace(typeof(IExceptionLogger), config.DependencyResolver.GetService(typeof(AppExceptionLogger))); 

Это работает без Owin, но он должен там будет хорошо.

Смежные вопросы