Calling external HTTP service using HttpClient fro

2019-03-14 10:21发布

I am calling an external service using HttpClient from within an ASP.Net MVC 4 Web Api project running on .Net Framework 4.5

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.

I have also tried using a simpler synchronous call with a WebClient as follows:

 // 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?

2条回答
一夜七次
2楼-- · 2019-03-14 10:33

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.

Thanks to Stephen Cleary for his blog post Async and Await which pointed me in the right direction.

查看更多
相关推荐>>
3楼-- · 2019-03-14 10:34

With the username and password call Httpclient. In case of API required authentication.

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

            }
}
查看更多
登录 后发表回答