2012-08-24 11 views
6

Ich verwende HttpClient, um meine MVC 4 Web API aufzurufen. In meinem Web-API-Aufruf gibt es ein Domänenobjekt zurück. Wenn etwas schief geht, wird eine HttpResponseException mit einer angepassten Nachricht auf den Server geworfen.HttpClient meldet keine Ausnahme von der Web-API zurückgegeben

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

Ich kann die benutzerdefinierte Fehlermeldung im Antworttextkörper mit IE F12 sehen. Jedoch, wenn ich es unter Verwendung HttpClient anrufe, erhalte ich nicht die kundenspezifische Fehlermeldung, nur den http-Code. Die "ReasonPhrase" ist immer "Nicht gefunden" für 404 oder "Interner Serverfehler" für 500 Codes.

Irgendwelche Ideen? Wie kann ich die benutzerdefinierte Fehlermeldung von der Web-API zurücksenden, während der normale Rückgabetyp mein Domänenobjekt bleibt?

+0

Welchen Webserver verwenden Sie, IIS oder ASP.NET Web Server? –

+0

Ich verwende IIS auf einem Windows 2008 R2. Auch hier ist es in Ordnung, wenn ich es über einen Browser anrufe. – Calvin

Antwort

14

(Putting meine Antwort hier für eine bessere Formatierung)

Ja ich es sah aber HttpResponseMessage keinen Körper Eigenschaft hat. Ich habe es selbst herausgefunden: response.Content.ReadAsStringAsync().Result;. Der Beispielcode:

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

Sie sollten vorsichtig sein, 'Result' direkt von' ReadAsAsync 'aufzurufen, da dies zu intermittierenden Threading-Problemen führen kann. Versuchen Sie stattdessen: 'var contentTask = response.Content.ReadAsAsync ();' gefolgt von 'contentTask.Wait();' und dann 'return contentTask.Result;' –

+0

Danke für den Tipp! – Calvin

+2

@ Sixto: Können Sie die Threading-Probleme beschreiben? Die [Ergebnis] (http://msdn.microsoft.com/en-us/library/vstudio/dd321468 (v = vs.110) .aspx) -Dokumente sagen "Der Get Accessor für diese Eigenschaft stellt sicher, dass der asynchrone Vorgang abgeschlossen ist Vor der Rückkehr." Es klingt, als wäre ein Aufruf von 'Wait' eingebaut. –

0

Die benutzerdefinierte Fehlermeldung würde im 'Körper' der Antwort sein.

+0

Ja, ich habe es gesehen, aber HttpResponseMessage hat keine Körpereigenschaft. Ich habe es selbst herausgefunden: 'response.Content.ReadAsStringAsync(). Result;'. Der Beispielcode: public T GetService (Zeichenfolge requestUri) { HttpResponseMessage Antwort = _client.GetAsync (requestUri) .Result; if (response.IsSuccessStatusCode) { Rückgabe response.Content.ReadAsAsync () .Result; } sonst { Zeichenfolge msg = response.Content.ReadAsStringAsync(). Result; neue Exception werfen (msg); } } – Calvin

+0

Eigentlich von Körper, meinte ich den Inhalt der Antwort. –

1

Ich habe etwas von der Logik ausgeklammert, wenn die Ausnahme von einer Antwort ergreift.

Dies macht es sehr einfach, die Ausnahme, innere Ausnahme, innere Ausnahme :) usw

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

Für eine vollständige Diskussion sehen this blog post zu extrahieren.

Verwandte Themen