4

我正在尝试使用 Elmah 启动并运行 MVC 5 WebAPI 应用程序。我找到的所有文档似乎都以“通过 nuget 安装”开始和结束,只是假设它会涵盖它,但我显然遗漏了一些东西。我已经通过 nuget 安装了 Elmah.MVC 2.1.1,并且可以在 /elmah 中查看错误日志。我能够请求一个无效的路由,并看到 Elmah 记录了由此产生的 404 错误,即使打开了 customErrors 也是如此。但是,如果我在控制器内或在控制器实例化期间生成未处理的错误,则不会将任何内容记录到 Elmah。例如:

[HttpGet, Route("api/health")]
[ApiExplorerSettings(IgnoreApi = true)]
public HttpResponseMessage GetHealth()
{
    throw new Exception("Whoops.");
}

我可以整天调用它,但 Elmah 日志中没有显示任何内容。添加标准的 HandleError 属性并没有改变任何东西,这里的一些文档似乎非常明确,我不应该创建自定义的 HandleError 属性。

我将 Ninject 用于 DI,类似地,如果我破坏依赖项绑定,我会得到一个很好的错误,如下所示:

{
    Message: "An error has occurred."
    ExceptionMessage: "An error occurred when trying to create a controller of type 'HealthController'. Make sure that the controller has a parameterless public constructor."
    ...
}

但在那种情况下,也没有任何东西可以进入 Elmah 日志。

我认为在这两种情况下,这是因为 MVC 正在为我处理这些错误(将异常格式化为 JSON 等),而不是将它们传递给 Elmah。我该如何配置,以便 Elmah 记录控制器中未处理的任何异常?

4

1 回答 1

1

弄清楚了。这类似于旧的 ExceptionFilter 机制,但更全局化,因为 ExceptionFilters 仅适用于来自特定控制器的未处理异常,而不适用于可能在堆栈中出现较高位置的错误。首先,我需要一个简单的 ExceptionLogger 将异常传递给 Elmah:

public class ElmahExceptionLogger : ExceptionLogger
{
    public override void Log(ExceptionLoggerContext context)
    {
        Elmah.ErrorLog.GetDefault(HttpContext.Current).Log(new Elmah.Error(context.Exception));
    }
}

然后在 WebApiConfig.cs 中添加:

public static void Register(HttpConfiguration config)
{
    // Web API routes
    config.MapHttpAttributeRoutes();

    config.Services.Add(typeof(IExceptionLogger), new ElmahExceptionLogger());
}

这确实需要最新最好的 MVC/WebAPI(目前为 5.1.1)。

于 2014-04-23T18:34:28.677 回答