2016-02-23 104 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