使用FilterAttributes进行Web API异常处理

时间:2017-04-05 10:10:12

标签: c# error-handling asp.net-web-api2

我有一个捕获错误并记录它们的过滤器,但我希望它返回正确的 HttpStatusCode ,以便我的客户端应用程序可以显示正确的错误消息。 目前,在我的filter属性的重写 OnException 方法中,我尝试通过将异常转换为 HttpException 来获取状态代码。 这看起来像这样:

public class LogExceptionFilterAttribute : ExceptionFilterAttribute
{

    // Private properties
    private readonly ILogProvider _logger;

    /// <summary>
    /// Our default constructor
    /// </summary>
    /// <param name="logger"></param>
    public LogExceptionFilterAttribute(ILogProvider logger)
    {
        _logger = logger;
    }

    /// <summary>
    /// Invoked when an exception has been thrown
    /// </summary>
    /// <param name="context">The context</param>
    public override async void OnException(HttpActionExecutedContext context)
    {

        // Get our user
        var requestContext = context.Request.GetRequestContext();
        var user = requestContext.Principal.Identity;

        // Create our response
        var message = await _logger.ErrorAsync(context.Exception, user);
        var content = new HttpResponseMessage
        {
            Content = new StringContent(message),
            StatusCode = GetStatusCodeFromException(context)
        };

        // Assign our response to our context
        context.Response = content;
    }

    /// <summary>
    /// Gets a status code from an error
    /// </summary>
    /// <param name="context">The context</param>
    /// <returns></returns>
    private static HttpStatusCode GetStatusCodeFromException(HttpActionExecutedContext context)
    {

        // Cast the exception as an HttpException
        var exception = context.Exception as HttpException;

        // If we don't have an exception
        if (exception != null)
        {

            // Return the HttpException code
            return (HttpStatusCode)exception.GetHttpCode();
        }

        // Return Internal Server Error
        return HttpStatusCode.InternalServerError;
    }
}

我意识到大多数错误无法转换为 HttpExceptions ,因此返回的状态代码将始终为500.

要解决此问题,我想为任何异常类型添加一个检查并相应地处理它们。 我决定最好的方法是创建一个这样的switch语句:

private static HttpStatusCode GetStatusCodeFromException(HttpActionExecutedContext context)
{

    // Cast the exception as an HttpException
    var exception = context.Exception as HttpException;

    // If there is still an exception, return the code
    if (exception != null)
        return (HttpStatusCode)exception.GetHttpCode();

    // Otherwise, work out what type of error we have
    switch(context.Exception.GetType().ToString())
    {
        case "NullReferenceException":
            return HttpStatusCode.BadRequest;
        default:
            return HttpStatusCode.InternalServerError;
    }
}

但现在我不确定这是否正确。 有人可以帮助我扩展这个或者告诉我一个更好的方法吗?

2 个答案:

答案 0 :(得分:0)

不是比较名称上的类型,而是实际检查类型本身更安全:

if (context.Exception is NullReferenceException)
{
    return HttpStatusCode.BadProgrammer;
}
else
{
    return HttpStatusCode.InternalServerError;
}

答案 1 :(得分:0)

我已将@Patrick Hofman的回答标记为正确,但我使用c#7制作了一个切换语句,如下所示:

private static HttpStatusCode GetStatusCodeFromException(HttpActionExecutedContext context)
{

    // Cast the exception as an HttpException
    var exception = context.Exception as HttpException;

    // If there is still an exception, return the code
    if (exception != null)
        return (HttpStatusCode)exception.GetHttpCode();

    // Witch on the exception type
    switch (context.Exception)
    {
        case ObjectNotFoundException ex:
            return HttpStatusCode.NotFound;
        default:
            return HttpStatusCode.InternalServerError;
    }
}