2012-04-23 83 views
11

我会从开始,是的,我们已经创建并正在使用从ExceptionFilterAttribute继承的异常过滤器。它是在我们的身份过滤器之后的应用程序启动配置中注册的,并且如果在我们的API中发生错误时发生错误,它的工作方式与预期相当。异常处理ASP.NET MVC Web API

这就是说,我正在寻找一种方法来处理在它到达API之前发生的错误。

推理:我们从不想要返回YSOD和/或IIS HTML错误。我们总是要打一个自定义异常过滤器/处理程序,以便我们可以正确处理日志记录并向用户返回JSON响应。

截至目前,使用Fiddler发出请求,我可以附加到w3wp.exe进程,并看到请求在Global.asax中找到了Application_BeginRequest方法。之后,它只是返回500响应。它从来没有在代码中打破例外,或者在那之后触发我的任何断点。它似乎正在返回一个IIS错误。我们永远不希望发生这种情况。我们需要能够捕获所有这些“低级”异常,记录它们,并向用户返回有意义的内容。

有什么我们可以做的处理错误之前,什么似乎是击中ASP.NET MVC Web API代码?

+0

这种感觉错了。你是否在某个库中抛出异常?为什么不在控制器中捕获异常并返回您自己选择的错误视图? – 2012-04-23 16:48:41

+1

这是使用ASP.NET MVC Web API,所以我们没有从控制器返回视图。我们返回JSON/XML响应。我在我的问题中还提到,在他们到达控制器之前,我需要一种处理异常的方法。现在我们拥有一个ExceptionFilter,一旦我们进入控制器,就可以在任何地方捕获异常,所以我们不必在每个操作中都有try/catch。 – phreak3eb 2012-04-23 18:23:20

+0

我不认为我完全理解你的问题。你试图准确捕捉什么类型的错误? – cecilphillip 2012-04-23 19:05:21

回答

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状态代码,并尽力为消费者提供合理或可能的答案。

+0

对于任何正在寻找关于调用'config.MessageHandlers.Insert()'的文档的文档,都可以[在WebAPI文档中](http://www.asp.net/web-api/overview/working-with -http/HTTP的消息处理程序)。 – 2012-05-17 18:15:50

+1

如果您想要Web API中的全局错误处理程序以及完整的例外信息,请在http://aspnetwebstack.codeplex.com/workitem/1001上投票选择此功能。 – 2013-05-09 00:57:49

+0

这看起来也是一个方便的变体:http:// blog.codeishard.net/2013/02/09/webapi-and-the-behavior-of-exceptions-and-an-alternative-configurable-way-to-deal/ – CrazyPyro 2013-09-20 23:13:30