如何使用HttpClient向REST API发送带有JSON的DELETE请求

50

我需要使用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。


您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Bradford Dillon
4个回答

100

虽然回答这个问题可能有些晚了,但我曾经遇到过类似的问题,并且以下代码对我有效。

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

38
你可以使用这些扩展方法:
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(JsonSerializer.Serialize(data), Encoding.UTF8, "application/json");
}

如果你还在使用Newtonsoft.JSON,将JsonSerializer.Serialize替换为JsonConvert.SerializeObject

谢谢!我想知道为什么微软没有像POST和PUT一样将这些扩展方法添加到https://msdn.microsoft.com/en-us/library/system.net.http.httpclientextensions.aspx。 - vkelman
1
з§Ѓжњ‰ж–№жі•дҢүз”ЁNewtonsoftJsonзљ„JsonConvert.SerializeObject。如жһњж‚ЁдҢүз”ЁSystem.Text.JsonпәЊиҮ·ж”№з”ЁJsonSerializer.SerializeгЂ‚ - Kebechet
1
@Kebechet,谢谢你的评论。我已经更新了我的答案,现在默认使用System.Text.Json,并提供了关于Newtonsoft的信息。毕竟,现在是2023年了。 - huysentruitw
1
谢谢。删除功能似乎包含在.NET Core 7中,但在.NET Core 6或更早版本中不包含。https://learn.microsoft.com/zh-cn/dotnet/api/system.net.http.json.httpclientjsonextensions?view=net-7.0 - undefined

3
Farzan Hajian的答案对我没有帮助,我可以设置请求内容,但实际上并未发送到服务器。
作为替代方案,您可以考虑使用X-HTTP-Method-Override头。这告诉服务器,您希望它将请求视为您发送了不同于实际发送的动词。您必须确保服务器正确处理此标头,但如果确实如此,您只需发布请求并添加:X-HTTP-Method-Override:DELETE到标题中,它将相当于具有主体的DELETE请求。

2
谢谢 - 这对我很有用。据我所知,.NET 不支持使用正文内容的 DELETE 请求。在我集成的 API 中,请求似乎已经被发送,但响应总是超时。这在 WebClient 和 HttpClient 中都发生了。您提出的方法覆盖标头的建议解决了这个问题。 - ShibbyUK

0

尝试一下

已编辑

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
}

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

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


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接