2012-11-04 9 views
18

Wołam do usługi zewnętrznej przy użyciu HttpClient od wewnątrz ASP.Net MVC projektu Api 4 internetowej uruchomionej na .Net Framework 4.5Wywołanie usługi HTTP zewnętrznych przy użyciu HttpClient z Web API działaniu

Przykładowy kod jest następujący (ignorować wartości zwracanych jest to przykładowy kod, aby przetestować wywołanie usługi zewnętrznej):

public class ValuesController : ApiController 
{ 
    static string _address = "http://api.worldbank.org/countries?format=json"; 
    private string result; 

    // GET api/values 
    public IEnumerable<string> Get() 
    { 
     GetResponse(); 
     return new string[] { result, "value2" }; 
    } 

    private async void GetResponse() 
    { 
     var client = new HttpClient(); 
     HttpResponseMessage response = await client.GetAsync(_address); 
     response.EnsureSuccessStatusCode(); 
     result = await response.Content.ReadAsStringAsync(); 
    } 
} 

Podczas gdy kod w prywatnej metody rzeczywiście działają mam problem jest, że Wirtualny kontroler() wywołuje GetResponse() ale nie czeka na wynik, ale zamiast tego natychmiast wykonuje powrót z wynikiem = null.

Próbowałem również stosując prostsze synchronicznego połączenia z WebClient następująco:

// GET api/values 
    public IEnumerable<string> Get() 
    { 
     //GetResponse(); 

     var client = new WebClient(); 

     result = client.DownloadString(_address); 

     return new string[] { result, "value2" }; 
    } 

który działa dobrze.

Co robię źle? Dlaczego funkcja Get() nie oczekuje zakończenia metody prywatnej w asynchronicznej próbie?

+0

Nie musisz również wywoływać GetResponse() z oczekiwaniem? W przeciwnym razie to nie będzie czekać na zakończenie tej metody ... a działanie kontrolera zakończy się bezpośrednio, pozostawiając wynik, który będzie nadal pusty. – jishi

+0

Tak, ale nie zdawałem sobie sprawy, że mogę oznaczyć Get() jako asynchroniczną, która jest wymagana do użycia. – Redeemed1

Odpowiedz

30

Aha, musiałem wykonać następujące czynności (powrót zadanie raczej wtedy nieważny):

// GET api/values 
    public async Task<IEnumerable<string>> Get() 
    { 
     var result = await GetExternalResponse(); 

     return new string[] { result, "value2" }; 
    } 

    private async Task<string> GetExternalResponse() 
    { 
     var client = new HttpClient(); 
     HttpResponseMessage response = await client.GetAsync(_address); 
     response.EnsureSuccessStatusCode(); 
     var result = await response.Content.ReadAsStringAsync(); 
     return result; 
    } 

Również nie zdawał sobie sprawy, mogę oznaczyć get() działanie jako async która jest co pozwoliło mi czekać na połączenie zewnętrzne.

Podziękowania dla Stephena Cleary za jego wpis na blogu Async and Await, który wskazał mi właściwy kierunek.

+0

Właśnie tego szukałem od ostatnich 3 dni! Proste, gdy je znacie :) Najkrótsza i najskuteczniejsza odpowiedź. –

0

Za pomocą nazwy użytkownika i hasła wywołaj Httpclient. W przypadku uwierzytelniania wymaganego przez API.

public async Task<ActionResult> Index() 
{ 

      const string uri = "https://testdoamin.zendesk.com/api/v2/users.json?role[]=agent"; 
      using (var client1 = new HttpClient()) 
      { 
       var header = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes("[email protected]:123456")));///username:password for auth 
       client1.DefaultRequestHeaders.Authorization = header; 
       var aa = JsonConvert.DeserializeObject<dynamic>(await client1.GetStringAsync(uri)); 

      } 
} 
+0

Karan, dziękuję za wysiłek tutaj, ale to nie jest związane z pytaniem. Twoja odpowiedź dotyczy uwierzytelniania, pytanie dotyczy zadań asynchronicznych wokół nieautoryzowanego interfejsu API – Redeemed1

Powiązane problemy