如何从异步ASP.NET Web API方法返回的任务中转换异常?

时间:2012-11-07 11:55:42

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

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

以下代码片段应该演示我正在讨论的异步API控制器方法的类型。

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

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

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

2 个答案:

答案 0 :(得分:4)

我使用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
    }
}

答案 1 :(得分:1)

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

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,那么您的工作将更加轻松。

修改

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