2016-05-11 20 views
7

Ho chiamato Web API dalla pagina ASP.NET su un clic del pulsante come di seguito. Questo è perfettamente lavorando bene anche se ho letto da qualche parte che creerà situazione di stallo in quanto non è async (grazie all'uso di .Result in linea client.PostAsJsonAsync(url, sd).Result;)Chiamata API Web dall'applicazione

si prega di suggerire modo migliore per aggiornare il codice.

private void CallApi(SurveyData sd) 
{ 

    using (var client = new HttpClient()) 
    {     

     string url = ConfigurationManager.AppSettings.Get("url"); 
     client.DefaultRequestHeaders.Accept.Clear(); 

     var response = client.PostAsJsonAsync(url, sd).Result; 

     if (response.IsSuccessStatusCode) 
     { 
      Response.Write("Success"); 
     } 
     else 
     { 
      Response.Write(response.StatusCode + " : Message - " + response.ReasonPhrase); 
     } 
    } 
} 
+0

Sì, la riga, var response = client.PostAsJsonAsync (url, sd) .Result; deve aspettare per la risposta. Puoi usare l'opzione controller asincrono nel tuo webapi. – Saadi

+0

Non sono sicuro, ma cosa succede se si esegue il metodo 'CallApi'' async' e si utilizza 'await' mentre si utilizza quel metodo? – Raghuveer

+2

Se non è MVC, il metodo può essere reso asincrono e quindi client.PostAsJsonAsync può essere atteso. Anche se è generalmente (come ho capito, cattiva pratica per contrassegnare i metodi void async). – Tim

risposta

1

Se non si desidera utilizzare async, è possibile utilizzare WebClient anziché HttpClient.

WebClient client = new WebClient(); 
string response = client.UploadString(RequestUrl, "POST", data); 
0

Si potrebbe riscrivere il metodo come metodo di async (nel qual caso io suggerirei che fornisce un tipo di ritorno di string):

private async Task<string> CallApi(SurveyData sd) 
{ 

    string result = String.Empty; 

    using (var client = new HttpClient()) 
    { 

     string url = ConfigurationManager.AppSettings["url"]; 
     client.DefaultRequestHeaders.Accept.Clear(); 

     var response = await client.PostAsJsonAsync(url, sd); 

     if (response.IsSuccessStatusCode) 
     { 
      result = "Success"; 
     } 
     else 
     { 
      result = response.StatusCode + " : Message - " + response.ReasonPhrase; 
     } 
    } 

    return result; 
} 

allora si potrebbe anche await i risultati di questa chiamata:

Response.Write(await CallApi(sd)); 

se la chiamata dovrebbe essere fatto da un altro metodo async. Altrimenti dovresti fare Response.Write(CallApi(sd).Result);, e non so se vedresti un significativo miglioramento delle prestazioni.

+0

Un metodo 'async' non può restituire una' stringa', deve invece restituire un 'Task '. Correggi il tipo di reso nella tua risposta. –

+0

@FedericoDipuma - Corretto. Grazie per la cattura :) – Tim

0

Si può provare con questo metodo

public async Task<HttpResponseMessage> GetHttpClientResult<T>(string baseUrl, string url, T requestParam, bool isExternalLink = false, 
      string acceptMediaVerb = "application/json", HttpMethod requestMethod = null) 
     { 
      try 
      { 
       HttpClient client = new HttpClient(); 
       HttpResponseMessage response = new HttpResponseMessage(); 
       if (!isExternalLink) 
       { 
        client.BaseAddress = new Uri(baseUrl); 
       } 
       if (!string.IsNullOrEmpty(acceptMediaVerb)) 
       { 
        if (acceptMediaVerb == "application/json") 
        { 
         client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
         if (requestMethod == HttpMethod.Get || requestMethod == null) 
         { 
          response = client.GetAsync(url).Result; 
         } 
         else if (requestMethod == HttpMethod.Post) 
         { 
          response = await client.PostAsJsonAsync(url, requestParam); 
         } 
        } 
       } 
       var context = new HttpContextWrapper(HttpContext.Current); 
       HttpRequestBase request = context.Request; 
       return response; 
      } 
      catch 
      { 
       return new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest); 
      } 
     } 

Questa è iniziato a scrivere come un metodo generico per gestire i metodi API con un URL di base configurata nell'applicazione stessa o qualsiasi richiesta web esterno