2012-08-24 35 views
6

Tôi đang sử dụng HttpClient để gọi api MVC 4 web của mình. Trong cuộc gọi API Web của tôi, nó trả về một đối tượng miền. Nếu có gì sai, một HttpResponseException sẽ được ném vào máy chủ, với một tin nhắn tùy chỉnh.HttpClient không báo cáo ngoại lệ được trả về từ API web

[System.Web.Http.HttpGet] 
    public Person Person(string loginName) 
    { 
     Person person = _profileRepository.GetPersonByEmail(loginName); 
     if (person == null) 
      throw new HttpResponseException(
     Request.CreateResponse(HttpStatusCode.NotFound, 
       "Person not found by this id: " + id.ToString())); 

     return person; 
    } 

Tôi có thể thấy thông báo lỗi tùy chỉnh trong nội dung phản hồi bằng IE F12. Tuy nhiên khi tôi gọi nó bằng cách sử dụng HttpClient, tôi không nhận được thông báo lỗi tùy chỉnh, chỉ có mã http. "ReasonPhrase" luôn là "Không tìm thấy" cho 404 hoặc "Lỗi máy chủ nội bộ" cho 500 mã.

Bất kỳ ý tưởng nào? Làm cách nào để gửi lại thông báo lỗi tùy chỉnh từ API Web, trong khi vẫn giữ kiểu trả về bình thường làm đối tượng miền của tôi?

+0

Máy chủ web nào bạn đang sử dụng, IIS hoặc ASP.NET Web Server? –

+0

Tôi đang sử dụng IIS trên Win 2008 R2. Một lần nữa, nó là ok khi tôi gọi nó bằng cách sử dụng một trình duyệt. – Calvin

Trả lời

14

(Đưa câu trả lời của tôi ở đây để định dạng tốt hơn)

Có, tôi nhìn thấy nó nhưng HttpResponseMessage không có một tài sản cơ thể. Tôi đã tự tìm ra: response.Content.ReadAsStringAsync().Result;. Mã mẫu:

public T GetService<T>(string requestUri) 
{ 
    HttpResponseMessage response = _client.GetAsync(requestUri).Result; 
    if(response.IsSuccessStatusCode) 
    { 
     return response.Content.ReadAsAsync<T>().Result; 
    } 
    else 
    { 
     string msg = response.Content.ReadAsStringAsync().Result; 
      throw new Exception(msg); 
    } 
} 
+4

Bạn nên cảnh giác với việc gọi 'Result' trực tiếp từ' ReadAsAsync 'bởi vì điều này có thể gây ra các vấn đề luồng liên tục. Thay vào đó, hãy thử: 'var contentTask = response.Content.ReadAsAsync ();' theo sau bởi 'contentTask.Wait();' và sau đó 'trả về contentTask.Result;' –

+0

Cảm ơn bạn đã tip! – Calvin

+2

@Sixto: Bạn có thể mô tả các vấn đề về luồng không? [Result] (http://msdn.microsoft.com/en-us/library/vstudio/dd321468 (v = vs.110) .aspx) tài liệu nói "Trình truy cập nhận cho thuộc tính này đảm bảo rằng thao tác không đồng bộ hoàn tất Trước khi trở về." Có vẻ như một cuộc gọi đến 'Chờ đợi' được cài sẵn. –

0

Thông báo lỗi tùy chỉnh sẽ nằm trong 'nội dung' của phản hồi.

+0

Có, tôi đã thấy nó nhưng HttpResponseMessage không có tài sản cơ thể. Tôi đã tự tìm ra: 'response.Content.ReadAsStringAsync(). Result;'. Mã mẫu: công khai T GetService (yêu cầu chuỗiUri) { HttpResponseMessage response = _client.GetAsync (requestUri) .Result; if (response.IsSuccessStatusCode) { trả lời trả lời.Content.ReadAsAsync () .Result; } else { chuỗi msg = response.Content.ReadAsStringAsync(). ném ngoại lệ mới (msg); } } – Calvin

+0

Thực ra theo nội dung, tôi có nghĩa là nội dung phản hồi. –

1

Tôi tính toán một số logic khi lấy ngoại lệ từ phản hồi.

này làm cho nó rất dễ dàng để trích xuất các ngoại lệ, ngoại lệ bên trong, ngoại trừ nội :), vv

public static class HttpResponseMessageExtension 
{ 
    public static async Task<ExceptionResponse> ExceptionResponse(this HttpResponseMessage httpResponseMessage) 
    { 
     string responseContent = await httpResponseMessage.Content.ReadAsStringAsync(); 
     ExceptionResponse exceptionResponse = JsonConvert.DeserializeObject<ExceptionResponse>(responseContent); 
     return exceptionResponse; 
    } 
} 

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; } 
} 

Đối với một cuộc thảo luận đầy đủ thấy this blog post.

Các vấn đề liên quan