异常处理 ASP.NET MVC Web API

11

首先,是的,我们创建并正在使用继承自ExceptionFilterAttribute的异常过滤器。它在应用启动时在我们的身份验证过滤器之后注册到配置中,并且如果API内部发生错误,则基本按预期工作。

话虽如此,我正在寻找一种处理在API到达之前发生的错误的方法。

原因: 我们永远不希望返回YSOD和/或IIS HTML错误。我们始终要命中自定义的异常过滤器/处理程序,以便我们正确处理日志记录并向用户返回JSON响应。

就目前而言,使用Fiddler进行请求,我可以附加到w3wp.exe进程并看到请求命中全局.asax中的Application_BeginRequest方法。之后,它只返回500响应。它在代码中从未出现异常或命中任何我的断点。似乎返回了一个IIS错误。我们绝不希望发生这种情况。我们需要能够捕获所有这些“低级”异常,记录下来,并向用户返回有意义的信息。

是否有什么我们可以做来处理在似乎到达ASP.NET MVC Web API代码之前的错误?


这种感觉有些不对。你在某个库中抛出异常吗?为什么不在控制器中捕获异常并返回自己选择的错误视图呢? - Robert Harvey
1
这是使用ASP.NET MVC Web API,因此我们不会从控制器返回视图。我们返回JSON/XML响应。我在我的问题中还提到了我需要一种在异常到达控制器之前处理异常的方法。现在我们有一个ExceptionFilter,在控制器内部任何地方捕获异常,因此我们不必在每个操作中都使用try/catch。 - jaryd
我不认为我完全理解你的问题。你究竟想要捕获哪些类型的错误? - cecilphillip
5
例如,如果有人使用错误的 JSON 格式请求服务,而 API 找不到相应的格式化程序,或者尝试使用 GET 时只有 POST 可用的控制器返回 405。这些都是在进入控制器之前发生的事情,这就是过滤器的作用。就好像在 ControllerDispatcher 中抛出了异常或使用了某种内置处理程序一样。我在配置中插入了一个自定义的 DelegatingHandler 以查看响应。我可以在调试器中看到返回的 InternalServerError 消息,但无法看到异常。 - jaryd
1个回答

4
尽管我喜欢Darin的答案,但在我们的情况下它不起作用,因为ASP.NET MVC Web API框架在内部抑制/处理异常,并且不会重新抛出以触发Global.asax中的Application_Error方法。我们的解决方案是这样的。
最终,我创建了一个自定义的DelegatingHandler,如下所示:
public class PrincipalHandler : DelegatingHandler
{
    protected const string PrincipalKey = "MS_UserPrincipal";
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        setAnonymousPrincipal();

        request = InitializeIdentity(request);

        return base.SendAsync(request, cancellationToken)
            .ContinueWith(r =>
                              {
                                  // inspect result for status code and handle accordingly
                                  return r.Result;
                              });
    }
}

我随后将它插入到HttpConfiguration中,以确保它是要被命中的第一个/最后一个处理程序。Web API中处理程序的工作方式是分层的。因此,每个请求要被命中的第一个处理程序,将在响应时被命中最后一个处理程序。至少这是我的理解,如果我错误了,请随意纠正。

public static void ConfigureApis(HttpConfiguration config)
{
    config.MessageHandlers.Insert(0, new PrincipalHandler());
}

通过使用这种方法,我们现在可以检查来自Web API和控制器的任何响应中返回的每个结果。这使我们能够处理由于未按预期返回而需要记录的任何日志。我们现在还可以更改返回的响应内容,以便IIS在看到特定的HTTP状态码时不会插入任何默认的HTML错误页面。
我唯一遇到的问题是,我希望他们在Web API的即将推出的版本中对此进行修改,因为它们没有将异常发送回从base.SendAsync()返回的任务。因此,我们只能依靠HTTP状态代码并尽力给消费者一个合理或可能的答案。

对于任何寻找有关如何连接到 config.MessageHandlers.Insert() 的文档的人,可以在WebAPI文档中找到。 - Josh Earl
1
如果您想在Web API中使用全局错误处理程序,并且希望完整的异常信息可用,请在http://aspnetwebstack.codeplex.com/workitem/1001投票支持此功能。 - Joe Daley
这看起来也是一个方便的变化:http://blog.codeishard.net/2013/02/09/webapi-and-the-behavior-of-exceptions-and-an-alternative-configurable-way-to-deal/ - CrazyPyro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接