我在.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<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();
}
}
虽然私有方法中的代码确实可以解决我的问题,但是Controller Get()调用了GetResponse(),但是它没有等待结果,而是立即执行带有result = null的返回。
我也尝试过使用WebClient进行更简单的同步调用,如下所示:
// GET api/values
public IEnumerable<string> Get()
{
//GetResponse();
var client = new WebClient();
result = client.DownloadString(_address);
return new string[] { result, "value2" };
}
工作正常。
我做错了什么?为什么Get()不等待异步样本中的私有方法完成?
答案 0 :(得分:35)
啊哈,我需要做以下事情(返回一个任务而不是空洞):
// 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;
}
此外,我还没有意识到我可以将Get()操作标记为async,这是允许我等待外部调用的原因。
感谢Stephen Cleary的博客文章Async and Await,它指出了我正确的方向。
答案 1 :(得分:0)
用用户名和密码调用Httpclient。如果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("test@gmail.com:123456")));///username:password for auth
client1.DefaultRequestHeaders.Authorization = header;
var aa = JsonConvert.DeserializeObject<dynamic>(await client1.GetStringAsync(uri));
}
}