web-dev-qa-db-ja.com

Httpclientこのインスタンスはすでに1つ以上の要求を開始しています。プロパティは、最初のリクエストを送信する前にのみ変更できます

.Net Core 2.1でアプリケーションを作成しています。Webリクエストにhttpクライアントを使用しています。問題は、時間を節約するために並列呼び出しを送信する必要があることであり、そのためにTask.WhenAll()メソッドを使用していますが、このメソッドにヒットすると、「このインスタンスはすでに1つ以上の要求を開始しています。プロパティのみ変更できます。最初のリクエストを送信する前に」以前はRestSharpを使用しており、すべてが問題ありませんでしたが、httpclientを使用したいと思っています。これがコードです:

public async Task<User> AddUser(string email)
{
    var url = "user/";
    _client.BaseAddress = new Uri("https://myWeb.com/");
    _client.DefaultRequestHeaders.Accept.Clear();
    _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(Constants."application/json"));
    _client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
    var json = new {email = email }
    var response = await _client.PostAsJsonAsync(url,json);
    if (response .IsSuccessStatusCode)
    { ....

ここにコンストラクタがあります:

private readonly HttpClient _httpClient;

public UserRepository(HttpClient httpClient)
{         
    _httpClient = httpClient;
}

メソッド呼び出し:

var user1 = AddUser("[email protected]");
var user2 = AddUser("[email protected]");

await Task.WhenAll(user1, user2);

そしてここにスタートアップの設定があります:

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

だから私は何が間違っているのですか? AddTransient()でAddSingletonを変更する必要がありますか、それとも他の問題がありますか?私が従ったチュートリアルではdisposeメソッドを使用していないため、少し混乱しています。

16
Ask

HttpClient.DefaultRequestHeaders(およびBaseAddress)は、リクエストを行う前に一度だけ設定する必要があります。 HttpClientは、使用後に変更しない限り、シングルトンとして安全に使用できます。

DefaultRequestHeadersを設定するのではなく、送信する各HttpRequestMessageにヘッダーを設定します。

var request = new HttpRequestMessage(HttpMethod.Post, url);
request.Headers.Accept.Clear();
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.Content = new StringContent("{...}", Encoding.UTF8, "application/json");
var response = await _client.SendAsync(request, CancellationToken.None);

置換"{...}"とJSON。

31
George Helyar

多分私の2セントは誰かを助けるでしょう。

アプリケーションのデバッグ時にページを更新すると、この問題が発生しました。

シングルトンを使用していましたが、更新するたびにベースアドレスを設定しようとしました。そのため、ベースアドレスが既に設定されているかどうかを確認するために、それをラップしました。

私にとっての問題は、baseAddressがすでに設定されていても、それを設定しようとしたことでした。 httpClientではこれを行うことはできません。

if (_httpClient.BaseAddress == null)
{
    _httpClient.BaseAddress = new Uri(baseAddress);
}
0
thatOneGuy