Я пишу фильтр исключений, который будет регистрировать исключения в Elmah, поэтому делаю что-то вроде этого:

class ExceptionLoggingFilter : System.Web.Http.Filters.IExceptionFilter
{
    public Task ExecuteExceptionFilterAsync(HttpActionExecutedContext actExecContext, 
                                            CancellationToken cancellationToken)
    {
        var httpContext = // what do I do here?
        var errorSignal = ErrorSignal.FromContext(httpContext); // this is Elmah
        errorSignal.Raise(actExecContext.Exception, httpContext);
    }
}

Моя проблема в том, что я не знаю, что поставить вместо вопроса с комментарием. Я пытался исследовать дерево элементов HttpActionExecutedContext, которое я получаю из сигнатуры метода, чтобы найти путь к System.Web.HttpContext, но я не могу найти никакого способа добраться туда.

Как мне здесь достичь своей цели?

3
Tomas Aschan 6 Фев 2015 в 19:32

2 ответа

Лучший ответ
Elmah.ErrorSignal.FromCurrentContext()

Использует HttpContext.Current под капотом, поэтому, хотя это могло сработать, я нашел лучший (хотя и более окольный) способ добраться до него:

var request = actionExecutedContext.Request;
object value;
if (request == null
    || !request.Properties.TryGetValue("MS_HttpContext", out value)
    || !(value is HttpContextBase))
    return null; // Actually I'm returning a Maybe monad here but that's off topic...
}
var httpContextBase = value as HttpContextBase;
return httpContextBase.ApplicationInstance.Context;

Я использую это вместе с реализацией монады, которая позволяет мне использовать ErrorSignal.FromCurrentContext() в качестве запасного варианта, и пока это работает хорошо.

4
Tomas Aschan 16 Фев 2015 в 09:12

Обратите внимание, что это, вероятно, будет работать только в том случае, если веб-API размещен в IIS (а не самостоятельно):

class ExceptionLoggingFilter : System.Web.Http.Filters.IExceptionFilter
{
    public Task ExecuteExceptionFilterAsync(HttpActionExecutedContext actExecContext, 
                                            CancellationToken cancellationToken)
    {
        //var httpContext = // what do I do here? NOTHING
        var errorSignal = ErrorSignal.FromCurrentContext(); // this is Elmah
        errorSignal.Raise(actExecContext.Exception);
    }
}
0
danludwig 6 Фев 2015 в 17:02