同步操作场景中的ExceptionFilter堆栈跟踪

我在Controller中有一个简单的同步动作,它抛出一个exception,如下所示:

[RoutePrefix("")] public class MyController : ApiController { [Route("")] public HttpResponseMessage Get() { throw new Exception("whatever"); return Request.CreateResponse(HttpStatusCode.OK, "response"); } } 

我还有一个ExceptionFilterAttribute来获取应用程序中发生的exception

 public class MyExceptionFilterAttribute : ExceptionFilterAttribute { public override void OnException(HttpActionExecutedContext actionContext) { var ex = actionContext.Exception; // Log ex, etc. } } 

一切正常,因为我确实在MyExceptionFilterAttribute获得了exception。 问题是堆栈跟踪。 这是它的样子:

 at System.Web.Http.Filters.ActionFilterAttribute.d__1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.ApiController.d__1.MoveNext()" 

所以我的问题是:如何获得“真正的”堆栈跟踪(这将指向控制器中发生exception的方法)?

更一般地说,因为显然有一些我不理解的东西,在这种情况下异步来自哪里? web api在遇到控制器方法时会自动创建异步任务吗?

我使用的是Web API v2.0( 软件包v5.0.0 ),无法升级到更新的版本(复杂的故事)。

更多信息:我遇到了这个问题所以我尝试inheritanceActionFilterAttribute而不是ExceptionFilterAttribute,但是当ActionFilterAttribute被击中时,堆栈跟踪看起来就像上面那样。

如果您不得不升级Web API包,那么最好的选择可能是避免使用ActionFilters来处理exception。

更好(和全局)的方法是创建ExceptionHandler来替换Web API配置中的默认实现:

 public class MyExceptionHandler : ExceptionHandler { public override void Handle(ExceptionHandlerContext context) { var ex = context.Exception; //log exception, do stuff context.Result = new InternalServerErrorResult(context.Request); } public override bool ShouldHandle(ExceptionHandlerContext context) { bool shouldHandle; //logic to check if you should handle the exception or not return shouldHandle; } } 

WebApiConfig.cs (假设config是你的HttpConfiguration对象):

 config.Services.Replace(typeof(IExceptionHandler), new MyExceptionHandler()); 

相反,如果您只想记录exception(而不是以某种方式处理它),那么您可以以类似的方式实现ExceptionLogger

 public class MyExceptionLogger : ExceptionLogger { public override void Log(ExceptionLoggerContext context) { MyLogger.Log(LogLevel.Error, context.Exception, "some message"); } } 

然后再次:

 config.Services.Replace(typeof(IExceptionLogger), new MyExceptionLogger());