如何从Web API中的HttpResponseMessage获取异常?

时间:2015-06-04 06:11:03

标签: c# .net asp.net-web-api

我正在尝试在Web API中实现自定义错误处理, 我需要从返回的HttpResponseMessage中获取异常。

我试图通过以下方式获取异常信息:

response.Content.ReadAsAsync<HttpError>().Result

但我无法访问结果对象,我在尝试时遇到异常, 所以我显然做错了。

无法弄清楚怎么做, 将不胜感激。

编辑:

我的客户端代码不相关,它只是一个GET请求,服务器代码:

控制器操作抛出异常:

if (condition == true)
{
    var response = new HttpResponseMessage(HttpStatusCode.BadRequest)
    {
        Content = new StringContent("Some Exception Related Message"),
        ReasonPhrase = "Some More Info"
    };

    throw new HttpResponseException(response);
}

我实现的DelegatingHandler的SendAsync方法得到响应, 这就是我想要获取上面控制器操作中抛出的异常的callstack的地方。

errorDetails = new ResponseErrorDetailsFull
{
    Message = "An error has occurred.",
    ExceptionMessage = response.ReasonPhrase,
    StackTrace = response.Content.ReadAsAsync<HttpError>().Result.StackTrace 
};

编辑#2

好的,所以我发现如果我创建一个ExceptionFilterAttribute和Override OnException(),请使用DelegatingHandler上的属性,我可以访问上面代码中提到的异常。

有人可以解释为什么这样做吗?

2 个答案:

答案 0 :(得分:2)

要在响应内容中获取HttpError,您的服务器端API代码需要在响应流中编写HttpError实例。

只有这样response.Content.ReadAsAsync<HttpError>().Result才会产生这些数据。

通常,如果服务器端代码抛出异常,则默认行为是HTTP 500(内部服务器错误)状态代码,在响应消息中没有任何可解析的内容。

在HTTP 400(错误请求)或其他此类非500(非200)错误的情况下,通常发送回响应数据。 (验证错误等) 在这种情况下,您可以从响应中读取数据。

通常对于任何错误情况,除非您的服务器端API代码没有在响应中写入已知类型,否则您无法从调用者端的响应中读取它。

请发布您的服务器端和客户端代码,以便我们为您提供进一步的帮助。

答案 1 :(得分:1)

我发现这个博客的例子非常好: http://nodogmablog.bryanhogan.net/2016/07/getting-web-api-exception-details-from-a-httpresponsemessage/

我采用了一些更新的代码:

if ((int)response.StatusCode >= 400)
 {
      exceptionResponse = JsonConvert.DeserializeObject<ExceptionResponse>(LogRequisicao.CorpoResposta);
      LogRequisicao.CorpoResposta = exceptionResponse.ToString() ;
      if (exceptionResponse.InnerException != null)
             LogRequisicao.CorpoResposta += "\r\n InnerException: " + exceptionResponse.ToString();
 }

使用对象:

public class ExceptionResponse
    {
        public string Message { get; set; }
        public string ExceptionMessage { get; set; }
        public string ExceptionType { get; set; }
        public string StackTrace { get; set; }
        public ExceptionResponse InnerException { get; set; }

        public override String ToString()
        {
            return "Message: " + Message + "\r\n "
                + "ExceptionMessage: " + ExceptionMessage + "\r\n "
                + "ExceptionType: " + ExceptionType + " \r\n "
                + "StackTrace: " + StackTrace + " \r\n ";           
        }  
    }