简体   繁体   English

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

[英]Calling external HTTP service using HttpClient from a Web API Action

I am calling an external service using HttpClient from within an ASP.Net MVC 4 Web Api project running on .Net Framework 4.5 我在.Net Framework 4.5上运行的ASP.Net MVC 4 Web Api项目中使用HttpClient调用外部服务

The sample code is as follows (ignore the return values as this is sample code to test calling an external service): 示例代码如下(忽略返回值,因为这是测试调用外部服务的示例代码):

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

While the code in the private method does indeed work the problem I have is that the Controller Get() calls the GetResponse() but it is not awaiting the result but instead immediately executes the return with result = null. 虽然私有方法中的代码确实可以解决我的问题,但是Controller Get()调用了GetResponse(),但是它没有等待结果,而是立即执行带有result = null的返回。

I have also tried using a simpler synchronous call with a WebClient as follows: 我也尝试过使用WebClient进行更简单的同步调用,如下所示:

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

        var client = new WebClient();

        result = client.DownloadString(_address);

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

which works fine. 哪个工作正常。

What am I doing wrong? 我究竟做错了什么? Why does the Get() not await the private method completion in the async sample? 为什么Get()不等待异步样本中的私有方法完成?

Aha, I needed to do the following (return a Task rather then 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;
    }

Also I hadn't realised I could mark the Get() operation as async which is what allowed me to await the external call. 此外,我还没有意识到我可以将Get()操作标记为async,这是允许我等待外部调用的原因。

Thanks to Stephen Cleary for his blog post Async and Await which pointed me in the right direction. 感谢Stephen Cleary的博客文章Async和Await ,它指出了我正确的方向。

With the username and password call Httpclient. 用户名和密码调用Httpclient。 In case of API required authentication. 如果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));

            }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM