【问题标题】:How to send DELETE with JSON to the REST API using HttpClient如何使用 HttpClient 将带有 JSON 的 DELETE 发送到 REST API
【发布时间】: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。

【问题讨论】:

标签: c# httpclient portable-class-library


【解决方案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");
    }
    

    【讨论】:

    【解决方案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 进行删除并且您正在使用版本字段。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-20
    相关资源
    最近更新 更多