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

以下のコードは、その方法の 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 に答える