如何使用 HttpClient 将带有 JSON 的 DELETE 发送到 REST API

Posted

技术标签:

【中文标题】如何使用 HttpClient 将带有 JSON 的 DELETE 发送到 REST API【英文标题】:How to send DELETE with JSON to the REST API using HttpClient 【发布时间】:2015-01-20 20:25:54 【问题描述】:

我必须使用 HttpClient 类向具有 JSON 内容的 REST API 服务发送删除命令,但无法使其正常工作。

API 调用:

DELETE /xxx/current

 "authentication_token": ""

因为我不能在下面的语句中添加任何内容:

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

我知道如何使用 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);

但我已经完成了没有 RestSharp。

【问题讨论】:

Possible place to start. 也可以查看 HttpRequestMessage 的 MSDN 文章。 【参考方案1】:

虽然回答这个问题可能已经晚了,但是 我遇到了类似的问题,下面的代码对我有用。

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

.NET 5 更新

.NET 5 引入了 JsonContent。下面是一个使用 JsonContent 的扩展方法:

public static async Task<HttpResponseMessage> DeleteAsJsonAsync<TValue>(this HttpClient httpClient, string requestUri, TValue value)

    HttpRequestMessage request = new HttpRequestMessage
    
        Content = JsonContent.Create(value),
        Method = HttpMethod.Delete,
        RequestUri = new Uri(requestUri, UriKind.Relative)
    ;
    return await httpClient.SendAsync(request);

【讨论】:

【参考方案2】:

您可以使用这些扩展方法:

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

【讨论】:

谢谢!我想知道为什么微软没有像 POST 和 PUT 那样将这些扩展方法添加到 msdn.microsoft.com/en-us/library/…。【参考方案3】:

Farzan Hajian 的回答仍然对我不起作用,我可以设置请求内容但实际上并没有发送到服务器。

作为替代方案,您可以考虑使用 X-HTTP-Method-Override 标头。这告诉服务器您希望它将请求视为您发送的动词与您实际发送的动词不同。您必须确保服务器正确处理此标头,但如果确实如此,您只需 POST 请求并将:X-HTTP-Method-Override:DELETE 添加到标头中,这将等同于带有正文的 DELETE 请求。

【讨论】:

谢谢 - 这对我有用。据我所知,.NET 对使用正文内容的 DELETE 请求不满意。使用我正在集成的 API,请求看起来像是正在发送,但响应总是超时。这发生在 WebClient 和 HttpClient 上。您对方法覆盖标头的建议解决了问题。【参考方案4】:

试试

已编辑

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

Here你可以找到非常相似的问题。

已编辑 我不确定为DELETE 请求传递请求正文是个好方法。特别是当这仅用于您的身份验证时。我更喜欢将authentication_token 放在标题中。这是因为在我的解决方案中,我不必解析整个请求正文来检查当前请求是否经过正确身份验证。其他请求类型呢?您是否总是在请求正文中传递authentication_token

【讨论】:

在某些情况下传递 DELETE 请求正文是完全可以接受和必要的,例如,如果您需要将实体传递给 DynamoDB 进行删除并且您正在使用版本字段。

以上是关于如何使用 HttpClient 将带有 JSON 的 DELETE 发送到 REST API的主要内容,如果未能解决你的问题,请参考以下文章

HttpClient postasync,带有自定义标头和应用程序/json,用于正文 C#

如何使用 HttpClient 将 JSON 数据发布到 Web API

httpclient - 如何将 Content-Disposition 设置为“application/json;”在多部分

WebAPI:HttpClient 响应字符串模型绑定

使用HttpClient 建立带有cookie 以及传送form 表单的请求

在 Android 中使用带有 post 参数的 HttpClient 和 HttpPost