使用Web API Action中的HttpClient调用外部HTTP服务

我在.Net Framework 4.5上运行的ASP.Net MVC 4 Web Api项目中使用HttpClient调用外部服务

示例代码如下(忽略返回值,因为这是测试调用外部服务的示例代码):

public class ValuesController : ApiController { static string _address = "http://api.worldbank.org/countries?format=json"; private string result; // GET api/values public IEnumerable 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(); } } 

虽然私有方法中的代码确实可以解决我的问题,但是Controller Get()调用了GetResponse(),但是它没有等待结果,而是立即执行带有result = null的返回。

我也尝试过使用WebClient进行更简单的同步调用,如下所示:

  // GET api/values public IEnumerable Get() { //GetResponse(); var client = new WebClient(); result = client.DownloadString(_address); return new string[] { result, "value2" }; } 

哪个工作正常。

我究竟做错了什么? 为什么Get()不等待异步样本中的私有方法完成?

啊哈,我需要做以下事情(返回一个任务而不是无效):

  // GET api/values public async Task> Get() { var result = await GetExternalResponse(); return new string[] { result, "value2" }; } private async Task GetExternalResponse() { var client = new HttpClient(); HttpResponseMessage response = await client.GetAsync(_address); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadAsStringAsync(); return result; } 

此外,我还没有意识到我可以将Get()操作标记为async,这是允许我等待外部调用的原因。

感谢Stephen Cleary的博客文章Async和Await ,它指出了我正确的方向。

用户名和密码调用Httpclient。 如果API需要身份validation。

  public async Task 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("test@gmail.com:123456")));///username:password for auth client1.DefaultRequestHeaders.Authorization = header; var aa = JsonConvert.DeserializeObject(await client1.GetStringAsync(uri)); } }