web-dev-qa-db-fra.com

Comment envoyer DELETE avec JSON à l'API REST à l'aide de HttpClient

Je dois envoyer une commande de suppression à un service API REST avec du contenu JSON en utilisant la classe HttpClient et je ne peux pas faire en sorte que cela fonctionne.

Appel API:

DELETE /xxx/current
{
 "authentication_token": ""
}

car je ne peux pas ajouter de contenu dans la déclaration ci-dessous:

HttpResponseMessage response = client.DeleteAsync(requestUri).Result;

Je sais comment faire fonctionner cela avec RestSharp:

var request = new RestRequest {
    Resource = "/xxx/current",
    Method = Method.DELETE,
    RequestFormat = DataFormat.Json
};

var jsonPayload = JsonConvert.SerializeObject(cancelDto, Formatting.Indented);

request.Parameters.Clear();
request.AddHeader("Content-type", "application/json");
request.AddHeader ("Accept", "application/json");
request.AddParameter ("application/json", jsonPayload, ParameterType.RequestBody);

var response = await client.ExecuteTaskAsync (request);

mais je l'ai fait sans RestSharp.

29
Tomasz Kowalczyk

Bien qu'il soit peut-être tard pour répondre à cette question, j'ai rencontré un problème similaire et le code suivant a fonctionné pour moi.

HttpRequestMessage request = new HttpRequestMessage
{
    Content = new StringContent("[YOUR JSON GOES HERE]", Encoding.UTF8, "application/json"),
    Method = HttpMethod.Delete,
    RequestUri = new Uri("[YOUR URL GOES HERE]")
};
await httpClient.SendAsync(request);
44
Farzan Hajian

Vous pouvez utiliser ces méthodes d'extension:

public static class HttpClientExtensions
{
    public static Task<HttpResponseMessage> DeleteAsJsonAsync<T>(this HttpClient httpClient, string requestUri, T data)
        => httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Delete, requestUri) { Content = Serialize(data) });

    public static Task<HttpResponseMessage> DeleteAsJsonAsync<T>(this HttpClient httpClient, string requestUri, T data, CancellationToken cancellationToken)
        => httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Delete, requestUri) { Content = Serialize(data) }, cancellationToken);

    public static Task<HttpResponseMessage> DeleteAsJsonAsync<T>(this HttpClient httpClient, Uri requestUri, T data)
        => httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Delete, requestUri) { Content = Serialize(data) });

    public static Task<HttpResponseMessage> DeleteAsJsonAsync<T>(this HttpClient httpClient, Uri requestUri, T data, CancellationToken cancellationToken)
        => httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Delete, requestUri) { Content = Serialize(data) }, cancellationToken);

    private static HttpContent Serialize(object data) => new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json");
}
25
huysentruitw

La réponse de Farzan Hajian ne fonctionnait toujours pas pour moi, j'ai pu définir le contenu de la demande mais elle n'a pas été envoyée au serveur.

Vous pouvez également envisager d'utiliser l'en-tête X-HTTP-Method-Override . Cela indique au serveur que vous souhaitez qu'il traite la demande comme si vous aviez envoyé un verbe différent de celui que vous avez réellement envoyé. Vous devrez vous assurer que le serveur gère correctement cet en-tête, mais si c'est le cas, vous pouvez simplement POST la demande et ajouter: X-HTTP-Method-Override:DELETE aux en-têtes et ce sera l'équivalent d'une demande DELETE avec un corps.

3
kevev22

Essayez avec

Modifié

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.your.url");

request.Method = "DELETE";

request.ContentType = "application/json";
request.Accept = "application/json";

using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
    string json = "{\"key\":\"value\"}";

    streamWriter.Write(json);
    streamWriter.Flush();
}

using (var httpResponse = (HttpWebResponse)request.GetResponse())
{
    // do something with response
}

Ici vous pouvez trouver un problème très similaire.

Modifié
Je ne suis pas sûr que le passage du corps de la demande pour DELETE soit une bonne approche. Surtout quand c'est uniquement à des fins d'authentification. Je préfère mettre authentication_token aux en-têtes. C'est parce que dans ma solution, je n'aurai pas à analyser l'ensemble du corps de la demande pour vérifier que la demande actuelle est correctement authentifiée. Qu'en est-il des autres types de demande? Passe-tu toujours authentication_token dans le corps de la demande?

0
rraszewski