【问题标题】:How to translate exceptions from Tasks returned by asynchronous ASP.NET Web API methods?如何翻译异步 ASP.NET Web API 方法返回的任务中的异常?
【发布时间】:2012-10-27 11:34:30
【问题描述】:

当(异步)ASP.NET Web API 控制器方法返回的任务引发异常时,我想将已知异常转换为HttpResponseException。有没有办法拦截这些异常,然后抛出HttpResponseException

下面的代码 sn-p 应该演示了我所说的异步 API 控制器方法的类型。

class ObjectApiController : ApiController
{
    public Task<Object> GetObjectByIdAsync(string id)
    [...]
}

如果我需要提供有关我正在尝试做的事情的更多信息,请告诉我。

编辑: 具体来说,我想知道是否有某种钩子可以用来拦截 ApiController 方法返回的任务中的异常,并将所述异常转换为 HttpResponseException。

【问题讨论】:

    标签: .net exception-handling asp.net-web-api task-parallel-library


    【解决方案1】:

    我使用 ExceptionFilter 来执行此操作:

    /// <summary>
    /// Formats uncaught exception in a common way, including preserving requested Content-Type
    /// </summary>
    public class FormatExceptionsFilterAttribute : ExceptionFilterAttribute
    {
    
        public override void OnException(HttpActionExecutedContext actionExecutedContext)
        {
            Exception exception = actionExecutedContext.Exception;
    
            if (exception != null)
            {            
                HttpRequestMessage request = actionExecutedContext.Request;
    
                // we shouldn't be getting unhandled exceptions
                string msg = "Uncaught exception while processing request {0}: {1}";
                AspLog.Error(msg.Fmt(request.GetCorrelationId().ToString("N"), exception), this); 
    
                // common errror format, without sending stack dump to the client
                HttpError error = new HttpError(exception.Message);
                HttpResponseMessage newResponse = request.CreateErrorResponse(
                    HttpStatusCode.InternalServerError,
                    error);
                actionExecutedContext.Response = newResponse; 
    
            }
        }
    
    }
    

    它是这样注册的:

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Filters.Add(new ApiControllers.FormatExceptionsFilterAttribute());
    
            // other stuff
        }
    }
    

    【讨论】:

      【解决方案2】:

      下面的代码只是其中一种方式:

      class ObjectApiController : ApiController
      {
          public Task<Object> GetObjectByIdAsync(string id)
          {
      
              return GetObjAsync().ContinueWith(task => { 
      
                  if(task.Status == TaskStatus.Faulted) { 
                      var tcs = TaskCompletionSource<object>();
      
                      // set the status code to whatever u need.
                      tcs.SetException(new HttpResponseException(HttpStatusCode.BadRequest));
      
                      return tcs.Task;
                  }
      
                  // TODO: also check for the cancellation if applicable
      
                  return task;
              });
          }
      }
      

      如果您使用 .NET 4.5 并希望使用 async/await,您的工作会更轻松。

      编辑

      根据你的 cmets,我猜你想要一些通用的东西。如果是这种情况,请按照@tcarvin 的建议使用异常过滤器。

      【讨论】:

      • 我在 .NET 4.5 上并正在尝试使用 await,但由于看起来越来越像 .NET 错误,我的顶级异常处理程序(捕获块)没有被调用.试图找出问题所在。
      • 我更多地考虑使用一些钩子来拦截从 ApiController 方法发出的所有未观察到的任务异常?这比在每个方法中处理任务异常要好得多。这可能是不可能的?
      • 重写我的 API 控制器方法后,我不知何故得到了异常处理和等待工作。然而我不知道我是如何修复它的:/
      • @aknuds1 那你为什么不使用异常过滤器呢?
      • 我对异常过滤器不是很熟悉,它们能处理来自任务的异常吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-15
      • 2016-08-30
      • 2019-01-22
      • 1970-01-01
      • 1970-01-01
      • 2018-10-23
      • 2011-08-28
      相关资源
      最近更新 更多