通过 Web API 操作使用 HttpClient 调用外部 HTTP 服务
Posted
技术标签:
【中文标题】通过 Web API 操作使用 HttpClient 调用外部 HTTP 服务【英文标题】:Calling external HTTP service using HttpClient from a Web API Action 【发布时间】:2012-11-04 21:15:24 【问题描述】:我在 .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();
虽然私有方法中的代码确实有效,但我遇到的问题是控制器 Get() 调用 GetResponse() 但它不等待结果,而是立即执行返回结果 = null。
我还尝试过使用 WebClient 进行更简单的同步调用,如下所示:
// GET api/values
public IEnumerable<string> Get()
//GetResponse();
var client = new WebClient();
result = client.DownloadString(_address);
return new string[] result, "value2" ;
效果很好。
我做错了什么?为什么 Get() 不等待异步示例中的私有方法完成?
【问题讨论】:
你不需要用 await 调用 GetResponse() 吗?否则,这不会等待该方法完成......并且您的控制器操作将直接完成,结果仍然为空。 是的,但我没有意识到我可以将 Get() 标记为异步,这是使用 await 所必需的。 【参考方案1】:啊哈,我需要执行以下操作(返回任务而不是 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;
我还没有意识到我可以将 Get() 操作标记为异步,这让我可以等待外部调用。
感谢 Stephen Cleary 的博文 Async and Await,它为我指明了正确的方向。
【讨论】:
这正是我过去 3 天以来一直在寻找的东西!一旦你知道它就很简单:) 最短和最有效的答案。【参考方案2】:用用户名和密码调用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));
【讨论】:
Karan,感谢您在这里的努力,但这与问题无关。您的回复与身份验证有关,该问题与围绕未经身份验证的 api 的异步任务有关以上是关于通过 Web API 操作使用 HttpClient 调用外部 HTTP 服务的主要内容,如果未能解决你的问题,请参考以下文章
显示 Json 数组 Angular 5 HttpClient
通过与客户端 (MVC) 一起使用 Web API 中的操作来验证电子邮件是不是存在于数据库中并进行远程验证?