2012-11-04 28 views
18

tôi kêu gọi một dịch vụ bên ngoài sử dụng HttpClient từ bên trong một ASP.Net MVC dự án Api 4 Web chạy trên .Net Framework 4.5Calling dịch vụ HTTP bên ngoài sử dụng HttpClient từ một hành động Web API

Mẫu mã được như sau (bỏ qua các giá trị trả lại vì đây là mẫu mã để kiểm tra gọi một dịch vụ bên ngoài):

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

Mặc dù mã trong phương pháp riêng nào thực sự làm việc vấn đề tôi có là Nhận Controller() gọi GetResponse() nhưng nó không phải chờ kết quả mà thay vào đó ngay lập tức thực hiện trả về với kết quả = null.

Tôi cũng đã cố gắng sử dụng một cuộc gọi đồng bộ đơn giản với một WebClient như sau:

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

     var client = new WebClient(); 

     result = client.DownloadString(_address); 

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

mà hoạt động tốt.

Tôi đang làm gì sai? Tại sao Get() không chờ kết thúc phương thức riêng tư trong mẫu async?

+0

bạn không cần phải gọi GetResponse() cũng đang chờ đợi chưa? Nếu không, điều đó sẽ không chờ đợi cho phương thức đó kết thúc ... và hành động điều khiển của bạn sẽ kết thúc trực tiếp để lại kết quả vẫn là null. – jishi

+0

Có nhưng tôi đã không nhận ra rằng tôi có thể đánh dấu Get() là async được yêu cầu để sử dụng chờ đợi. – Redeemed1

Trả lời

30

Aha, tôi cần phải làm như sau (trả về một nhiệm vụ chứ không phải sau đó void):

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

Ngoài ra tôi đã không nhận ra tôi có thể đánh dấu sự hoạt động Get() như async đó là những gì cho phép tôi đang chờ cuộc gọi bên ngoài.

Cảm ơn Stephen Cleary vì bài đăng trên blog của mình Async and Await đã chỉ cho tôi đúng hướng.

+0

Chỉ là những gì tôi đang tìm kiếm từ 3 ngày qua! Đơn giản một khi bạn biết nó :) Câu trả lời ngắn nhất và hiệu quả nhất. –

0

Với tên người dùng và mật khẩu, hãy gọi Httpclient. Trong trường hợp xác thực yêu cầu 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, cảm ơn vì nỗ lực của bạn ở đây nhưng điều này không liên quan đến câu hỏi. Phản hồi của bạn liên quan đến Xác thực, câu hỏi liên quan đến Công việc không đồng bộ xung quanh api không được xác thực – Redeemed1

Các vấn đề liên quan