182 votes

Envoyer un message HTTP POST dans ASP.NET Core en utilisant HttpClient PostAsJsonAsync

Je veux envoyer un objet dynamique comme

new { x = 1, y = 2 };

comme corps du message HTTP POST. J'essaie donc d'écrire

var client = new HttpClient();

mais je ne trouve pas de méthode

client.PostAsJsonAsync()

J'ai donc essayé d'ajouter le paquet Microsoft.AspNetCore.Http.Extensions à project.json et d'ajouter

using Microsoft.AspNetCore.Http.Extensions; 

pour utiliser la clause. Cependant, cela ne m'a pas aidé.

Quel est donc le moyen le plus simple d'envoyer une requête POST avec un corps JSON en ASP.NET Core ?

0 votes

On se demande pourquoi cet article ne contient pas d'exemple pour le POST docs.microsoft.com/en-us/dotnet/csharp/tutorials/

261voto

Set Points 21500

Vous devez ajouter une référence au paquet "Microsoft.AspNet.WebApi.Client" (lire cet article pour les échantillons).

Sans aucune extension supplémentaire, vous pouvez utiliser le système standard PostAsync méthode :

client.PostAsync(uri, new StringContent(jsonInString, Encoding.UTF8, "application/json"));

jsonInString que vous pouvez obtenir en appelant JsonConvert.SerializeObject(<your object>);

1 votes

Mais Microsoft.AspNet.WebApi.Client ne ressemble pas à la bibliothèque ASP.NET Core RC2. Et la deuxième façon est vraiment trop de répétition de code (((

1 votes

@Rem pourquoi ne créez-vous pas une HttpClient méthode d'extension( PostAsJsonAsync ) pour utiliser la deuxième voie. Elle vous permet d'éviter la répétition du code.

2 votes

Bien sûr. Mais j'ai posé la question afin de savoir si j'ai manqué quelque chose. Je ne peux pas croire que cela n'a pas encore été implémenté dans Core !

122voto

stop-cran Points 2461

J'utilise cette classe :

public class JsonContent : StringContent
{
    public JsonContent(object obj) :
        base(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json")
    { }
}

Exemple d'utilisation :

new HttpClient().PostAsync("http://...", new JsonContent(new { x = 1, y = 2 }));

5 votes

Pourquoi pas une méthode d'extension ? public static class JsonContent { public Task<?> PostAsJSonAsync(this HttpClient client, object toSerializeAsJson) { ... } }

2 votes

J'aime l'approche de la classe JsonContent

0 votes

Est-ce que cet ensemble Content-Length: En-tête HTTP ?

13voto

Serj Sagan Points 2731

J'ajouterais à la réponse acceptée que vous voudriez aussi ajouter la Accept à l'en-tête httpClient :

httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

10voto

Ogglas Points 1

Microsoft recommande maintenant d'utiliser un IHttpClientFactory avec les avantages suivants :

  • Fournit un emplacement central pour nommer et configurer les systèmes logiques. HttpClient instances. Par exemple, un client nommé github peut être enregistré et configuré pour accéder à GitHub. Un client par défaut peut être enregistré pour un accès général.
  • Codifie le concept d'intergiciel sortant via des gestionnaires de délégation dans HttpClient . Fournit des extensions pour les middleware basés sur Polly afin de tirer pour tirer parti des gestionnaires de délégation dans HttpClient .
  • Gère la mise en commun et la durée de vie de la base de données HttpClientMessageHandler instances. La gestion automatique permet d'éviter les problèmes courants de DNS (système de nom de domaine) qui surviennent lors de la gestion manuelle de HttpClient de vie.
  • Ajoute une expérience de journalisation configurable (par l'intermédiaire de ILogger ) pour toutes les requêtes envoyées par les clients créés par la fabrique.

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.1

Mise en place :

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHttpClient();
        // Remaining code deleted for brevity.

Exemple de POST :

public class BasicUsageModel : PageModel
{
    private readonly IHttpClientFactory _clientFactory;

    public BasicUsageModel(IHttpClientFactory clientFactory)
    {
        _clientFactory = clientFactory;
    }

    public async Task CreateItemAsync(TodoItem todoItem)
    {
        var todoItemJson = new StringContent(
            JsonSerializer.Serialize(todoItem, _jsonSerializerOptions),
            Encoding.UTF8,
            "application/json");

        var httpClient = _clientFactory.CreateClient();

        using var httpResponse =
            await httpClient.PostAsync("/api/TodoItems", todoItemJson);

        httpResponse.EnsureSuccessStatusCode();
    }

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.1#make-post-put-and-delete-requests

7voto

Mark Lagendijk Points 1232

Si vous utilisez .NET 5 ou une version supérieure, vous pouvez (et devez) utiliser la fonction PostAsJsonAsync méthode d'extension de System.Net.Http.Json :

httpClient.PostAsJsonAsync(url, new { 
    x = 1, 
    y = 2 
});

Si vous utilisez une ancienne version de .NET Core, vous pouvez implémenter la fonction d'extension vous-même :

public static class HttpClientExtensions
{
    public static Task<HttpResponseMessage> PostJsonAsync(this HttpClient httpClient, string url, object body)
    {
        var bodyJson = JsonSerializer.Serialize(body);
        var stringContent = new StringContent(bodyJson, Encoding.UTF8, "application/json");
        return httpClient.PostAsync(url, stringContent);
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X