2012-08-24 18 views
6

Używam HttpClient do wywoływania mojego interfejsu API MVC 4. W moim wywołaniu Web API zwraca obiekt domeny. Jeśli coś pójdzie nie tak, na serwerze zostanie przesłany HttpResponseException z niestandardowym komunikatem.HttpClient nie zgłasza wyjątku zwróconego przez interfejs API WWW

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

Widzę dostosowany komunikat o błędzie w treści odpowiedzi za pomocą IE F12. Jednak gdy wywołuję to przy użyciu HttpClient, nie otrzymuję dostosowanego komunikatu o błędzie, tylko kod http. "ReasonPhrase" jest zawsze "Nie znaleziono" dla 404 lub "Internal Server Error" dla 500 kodów.

Wszelkie pomysły? Jak wysłać komunikat o błędzie niestandardowym z interfejsu API WWW, zachowując jednocześnie normalny typ zwracania jako obiekt mojej domeny?

+0

Jakiego serwera używasz, serwera sieci Web IIS lub ASP.NET? –

+0

Używam IIS na Win 2008 R2. Ponownie, jest OK, gdy zadzwonię do niego za pomocą przeglądarki. – Calvin

Odpowiedz

14

(Putting moją odpowiedź tutaj dla lepszego formatowania)

Tak widziałem go ale HttpResponseMessage nie posiada własności ciała. Sam to wymyśliłem: response.Content.ReadAsStringAsync().Result;. Przykładowy kod:

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

Powinieneś być ostrożny przy wywoływaniu 'Result' bezpośrednio z' ReadAsAsync 'ponieważ może to powodować sporadyczne problemy z wątkami. Zamiast tego spróbuj: 'var contentTask = response.Content.ReadAsAsync ();' po którym następuje 'contentTask.Wait();', a następnie 'return contentTask.Result;' –

+0

Dzięki za napiwek! – Calvin

+2

@Sixto: Czy możesz opisać problemy z wątkami? Dokument [Wynik] (http://msdn.microsoft.com/en-us/library/vstudio/dd321468 (v = kontra.110) .aspx) mówi: "Przystawka uzyskująca dostęp do tej właściwości zapewnia zakończenie operacji asynchronicznej przed powrotem. " To brzmi jak wbudowane jest wywołanie 'Wait'. –

0

Niestandardowy komunikat o błędzie znajduje się w "treści" odpowiedzi.

+0

Tak, widziałem to, ale HttpResponseMessage nie ma właściwości ciała. Sam to wymyśliłem: 'response.Content.ReadAsStringAsync(). Wynik;'. Kod próbki: społeczeństwa t getService (ciąg requestUri) { HttpResponseMessage odpowiedzi = _client.GetAsync (requestUri) .Result; if (response.IsSuccessStatusCode) { odpowiedź zwrotna.Content.ReadAsAsync () .Result; } else { ciąg msg = response.Content.ReadAsStringAsync(). Wynik; throw new Exception (msg); } } – Calvin

+0

Właściwie według ciała, miałem na myśli treść odpowiedzi. –

1

Rozważyłem część logiki przy chwytaniu wyjątku od odpowiedzi.

To sprawia, że ​​bardzo łatwo wyodrębnić wyjątek, wyjątek wewnętrzny, wewnętrzny wyjątek :) itp

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

zawiera pełne omówienie zobaczyć this blog post.

Powiązane problemy