2013-03-04 16 views
18

ho questa riga di codiceottenere risposta da PostAsJsonAsync

var response = new HttpClient().PostAsJsonAsync(posturi, model).Result; 

Il controller WebAPI Chiamato restituisce un bool per assicurarsi che l'oggetto è stato salvato, ma come faccio a restituire quella risposta bool?

+0

Utilizzare il debugger per esplorare l'oggetto risposta. Invita anche Fiddler a vedere cosa viene pubblicato e ricevuto. Usa anche await - piuttosto che .Response se vuoi usarlo in modo asincrono. – niico

risposta

43

continuerà ad ottenere dal contenuto:

var httpClient = new HttpClient(); 
var response = httpClient.PostAsJsonAsync(posturi, model).Result; 
bool returnValue = response.Content.ReadAsAsync<bool>().Result; 

Ma, questo è veramente ingenuo approccio per modo rapido per ottenere il risultato. PostAsJsonAsync e ReadAsAsync non è progettato per fare in questo modo, essi sono progettati per supportare async await programmazione, in modo che il codice dovrebbe essere:

var httpClient = new HttpClient(); 
var response = await httpClient.PostAsJsonAsync(posturi, model); 
bool returnValue = await response.Content.ReadAsAsync<bool>(); 

Inoltre, invece di utilizzare un flag per verificare se un oggetto viene salvato o no, si dovrebbe utilizzare i codici HTTP restituendo 200 OK per determinare se il salvataggio è riuscito.

+0

Lee, per questa particolare situazione c'è un motivo molto specifico per cui non sono in questo caso –

+2

Perché ".Result" e il blocco invece di "attendere"? –

3

Se si chiama la versione generica, dovrebbe dare indietro il bool:

var response = new HttpClient().PostAsJsonAsync<bool>(posturi, model).Result; 

Almeno secondo the docs.

+1

Penso che influenzi la richiesta, non la risposta. – Timmerz

10

Fin dalla sua un'operazione asincrona non immediatamente fare .Result come sbagliato

Invece è necessario farlo asincrona in questo modo:

var HttpClient = new HttpClient()

var task = httpClient.PostAsJsonAsync(posturi, model) 
         .ContinueWith(x => x.Result.Content.ReadAsAsync<bool>().Result); 

    // 1. GETTING RESPONSE - NOT ASYNC WAY 
    task.Wait(); //THIS WILL HOLD THE THREAD AND IT WON'T BE ASYNC ANYMORE! 
    bool response = task.Result 

    // 2. GETTING RESPONSE - TASK ASYNC WAY (usually used in < .NET 4.5 
    task.ContinueWith(x => { 
           bool response = x.Result 
          }); 

    // 3. GETTING RESPONSE - TASK ASYNC WAY (usually used in >= .NET 4.5 
    bool response = await task; 

NOTA: Li ho appena scritti qui, quindi non li ho testati ma più o meno è quello che vuoi.

Spero che aiuti!

+1

Mi consiglia di non inserire httpClient in un'istruzione using: https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/ – Xander

3

Ho usato HttpStatusCode per controllare il risultato.

public HttpStatusCode PostStaffPositions(Foo foo) 
    { 
     string uri = myapiuri; 

     using (HttpClient httpClient = new HttpClient()) 
     { 
      var response = httpClient.PostAsJsonAsync(uri, foo).Result; 
      return response.StatusCode; 
     } 
    } 

E poi nel controller controllare in questo modo:

HttpStatusCode update = staffrest.PostStaffPositions(foo); 
      if (update == HttpStatusCode.OK) 
      { 
       //Update Succeed 
      } 
      else 
      { 
       //Update Failed 
      } 
28

La risposta accettata è tecnicamente corretta, ma blocca il thread corrente sulle chiamate verso .Result. Se stai usando .NET 4.5 o versioni successive, dovresti evitarlo in quasi tutte le situazioni. Invece, utilizzare la versione asincrona equivalente (non bloccante):

var httpClient = new HttpClient(); 
var response = await httpClient.PostAsJsonAsync(posturi, model); 
bool returnValue = await response.Content.ReadAsAsync<bool>(); 

noti che il metodo contenente il codice sopra deve essere contrassegnato async, e dovrebbe essere anch'esso await ed.

Problemi correlati