web-dev-qa-db-fra.com

Httpclient Cette instance a déjà démarré une ou plusieurs demandes. Les propriétés ne peuvent être modifiées qu'avant l'envoi de la première demande

Je crée une application dans .Net Core 2.1 et j'utilise le client http pour les requêtes Web. Le problème est que je dois envoyer des appels parallèles pour gagner du temps et pour cela j'utilise la méthode Task.WhenAll () mais lorsque j'appuie sur cette méthode, j'obtiens l'erreur "Cette instance a déjà démarré une ou plusieurs demandes. Les propriétés ne peuvent être modifiées que avant d'envoyer la première demande "Auparavant, j'utilisais RestSharp et tout allait bien, mais je veux utiliser httpclient. Voici le code:

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)
    { ....

Voici le constructeur:

private readonly HttpClient _httpClient;

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

Appel de méthode:

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

await Task.WhenAll(user1, user2);

et voici la configuration de démarrage:

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

Alors qu'est-ce que je fais mal? Dois-je changer AddSingleton avec AddTransient () ou y a-t-il un autre problème. Une autre question dois-je utiliser _client.Dispose () après la réponse parce que le tutoriel que j'ai suivi n'a pas utilisé la méthode dispose donc je suis peu confus là-dedans.

16
Ask

HttpClient.DefaultRequestHeaders (et BaseAddress) ne doivent être définis qu'une seule fois, avant de faire des demandes. HttpClient n'est sûr à utiliser comme singleton que si vous ne le modifiez pas une fois qu'il est utilisé.

Plutôt que de définir DefaultRequestHeaders, définissez les en-têtes sur chaque HttpRequestMessage que vous envoyez.

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

Remplacer "{...}" avec votre JSON.

31
George Helyar

Peut-être que mes deux cents aideront quelqu'un.

J'ai rencontré ce problème lors de l'actualisation de la page lors du débogage de l'application.

J'utilisais un singleton, mais à chaque rafraîchissement, il essayait de définir l'adresse de base. Je l'ai donc simplement emballé dans une vérification pour voir si l'adresse de base avait déjà été définie.

Le problème pour moi était qu'il essayait de définir l'adresse de base, même s'il était déjà défini. Vous ne pouvez pas faire cela avec un httpClient.

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