Подтвердить что ты не робот

Вызов внешнего HTTP-сервиса с использованием HttpClient из действия веб-API

Я вызываю внешнюю службу с использованием HttpClient из проекта ASP.Net MVC 4 Web Api, работающего на .Net Framework 4.5

Пример кода выглядит следующим образом (игнорируйте возвращаемые значения, так как это пример кода для проверки вызова внешней службы):

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() не ждет завершения частного метода в асинхронном образце?

4b9b3361

Ответ 1

Ага, мне нужно было сделать следующее (верните Задачу, а затем пустоту):

 // 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, что и позволило мне ждать внешнего вызова.

Спасибо Стивен Клири за его сообщение в блоге Async и Await, который указал мне в правильном направлении.

Ответ 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("[email protected]:123456")));///username:password for auth
                client1.DefaultRequestHeaders.Authorization = header;
               var aa = JsonConvert.DeserializeObject<dynamic>(await client1.GetStringAsync(uri));

            }
}