.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()が非同期サンプルでプライベートメソッドの完了を待たないのはなぜですか?
ああ、私は次のことをする必要がありました(無効ではなくタスクを返します):
// 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 に感謝します。
ユーザー名とパスワードを使用して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));
}
}