2016-02-23 143 views
2

我试图从我的HttpRequestException中记录失败的请求。通过HttpRequestException获取失败请求的响应正文

我的服务器在响应主体返回了错误代码附加JSON有效负载。我需要访问该JSON。如果出现错误的请求,我该如何阅读响应主体?我知道实际的回应不是空的。这是一个API,我确认它会返回带有4xx状态代码的JSON有效负载,提供有关错误的详细信息。

我该如何访问它?这里是我的代码:

using (var httpClient = new HttpClient()) 
{ 
    try 
    { 
     string resultString = await httpClient.GetStringAsync(endpoint); 
     var result = JsonConvert.DeserializeObject<...>(resultString); 
     return result; 
    } 
    catch (HttpRequestException ex) 
    { 
     throw ex; 
    } 
} 

我想在throw ex行获得的数据,但我无法找到一个方法。

+0

我不知道这是否可以帮助你。 http://stackoverflow.com/questions/10928528/receiving-json-data-back-from-http-request –

回答

3

究竟为@弗雷德里克建议,如果你使用GetAsync方法,你会得到正确的HttpResponseMessage对象,提供有关响应的详细信息。要获取详细信息时出现错误,您可以从响应内容desearlize错误到Exception或您的自定义异常对象象下面这样:

public static Exception CreateExceptionFromResponseErrors(HttpResponseMessage response) 
{ 
    var httpErrorObject = response.Content.ReadAsStringAsync().Result; 

    // Create an anonymous object to use as the template for deserialization: 
    var anonymousErrorObject = 
     new { message = "", ModelState = new Dictionary<string, string[]>() }; 

    // Deserialize: 
    var deserializedErrorObject = 
     JsonConvert.DeserializeAnonymousType(httpErrorObject, anonymousErrorObject); 

    // Now wrap into an exception which best fullfills the needs of your application: 
    var ex = new Exception(); 

    // Sometimes, there may be Model Errors: 
    if (deserializedErrorObject.ModelState != null) 
    { 
     var errors = 
      deserializedErrorObject.ModelState 
            .Select(kvp => string.Join(". ", kvp.Value)); 
     for (int i = 0; i < errors.Count(); i++) 
     { 
      // Wrap the errors up into the base Exception.Data Dictionary: 
      ex.Data.Add(i, errors.ElementAt(i)); 
     } 
    } 
    // Othertimes, there may not be Model Errors: 
    else 
    { 
     var error = 
      JsonConvert.DeserializeObject<Dictionary<string, string>>(httpErrorObject); 
     foreach (var kvp in error) 
     { 
      // Wrap the errors up into the base Exception.Data Dictionary: 
      ex.Data.Add(kvp.Key, kvp.Value); 
     } 
    } 
    return ex; 
} 

用法:

 using (var client = new HttpClient()) 
     { 
      var response = 
       await client.GetAsync("http://localhost:51137/api/Account/Register"); 


      if (!response.IsSuccessStatusCode) 
      { 
       // Unwrap the response and throw as an Api Exception: 
       var ex = CreateExceptionFromResponseErrors(response); 
       throw ex; 
      } 
     } 

这里的source文章,详细了解处理HttpResponseMessage及其内容。

1

本质上是@RyanGunn发布但在您的代码中实现的。

你应该能够ReadAsStringAsyncresultString.Content

我上除了我们使用switch语句来检查,我们打算在DeserializeObject行之前返回各HttpStatusCodes,它采用类似的代码的SDK工作。

using (var httpClient = new HttpClient()) 
{ 
    try 
    { 
     string resultString = await httpClient.GetStringAsync(endpoint); 
     var result = JsonConvert.DeserializeObject<...>(resultString.Content.ReadAsStringAsync().Result); 
     return result; 
    } 
    catch (HttpRequestException ex) 
    { 
     throw ex; 
    } 
} 
0

使用GetAsync而不是GetStringAsyncGetAsync不会抛出异常并允许您访问响应内容,状态码和您可能需要的任何其他头文件。

有关更多信息,请参见此page