web-dev-qa-db-ja.com

Web APIアクションからHttpClientを使用して外部HTTPサービスを呼び出す

.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()を呼び出しますが、結果を待っているのではなく、すぐに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()が非同期サンプルでプライベートメソッドの完了を待たないのはなぜですか?

25
Redeemed1

ああ、私は次のことをする必要がありました(無効ではなくタスクを返します):

 // 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 に感謝します。

36
Redeemed1

ユーザー名とパスワードを使用して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));

            }
}
0
Karan Singh