1

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

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

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

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

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

4

2 回答 2

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
    }
}
于 2012-11-07T13:18:30.877 回答
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 的建议使用异常过滤器。

于 2012-11-07T12:48:52.063 回答