C# HttpClient.SendAsync 导致错误,无法发送具有此谓词类型的内容正文

C# HttpClient.SendAsync causes error, cannot send a content-body with this verb-type

提问人:Sujoy 提问时间:2/23/2022 更新时间:2/23/2022 访问量:3502

问:

我收到错误,无法发送带有此谓词类型的内容正文。我正在从 C# VSTO 桌面应用程序调用 GET 终结点。我做错了什么。

public static string GetCentralPath(LicenseMachineValidateRequestDTO licenseMachine)
{
    using (var client = new HttpClient())
    {
        client.DefaultRequestHeaders.Authorization =    new AuthenticationHeaderValue("Bearer", Properties.Settings.Default.Properties["JWT"].DefaultValue.ToString());
        var request = new HttpRequestMessage
        {
            Method = HttpMethod.Get,
            RequestUri = new Uri($"{Constants.URL.APIBase}licensemachine/GetCentralPath"),
            Content = new StringContent(JsonConvert.SerializeObject(licenseMachine), Encoding.UTF8, "application/json"),
        };
        
        using (HttpResponseMessage response = client.SendAsync(request).GetAwaiter().GetResult()) // Causing ERROR
        {
            var result = GetStringResultFromHttpResponseMessage(response, true);
            if (string.IsNullOrEmpty(result))
                return null;
            return JsonConvert.DeserializeObject<string>(result);
        }
    }
}

端点如下所示:

[HttpGet("GetCentralPath")]
public async Task<IActionResult> GetCentralPath(LicenseMachineValidateRequestDTO dto)
{
    // Some code
}
C# .net-core httpclient 获取请求 sendasync

评论

1赞 Matt 2/23/2022
该错误指出无法将 HttpRequestMessage 的内容正文定义为 Get。如果需要内容,则使用 HttpMethod Post(同时更改控制器上的定义)
0赞 Sujoy 2/23/2022
必须有一种适当的方法来实现这一目标。为什么 API 层会因为一些错误的客户端行为而受到影响。如果我调用第三方 API,我是否应该请求供应商进行更改。
0赞 jdweng 2/23/2022
将 GET 更改为 PUT。当您在服务器上收到请求或在客户端上收到响应时,将使用 GET。您正在客户端发送,需要使用 POST。
1赞 Bradley Uffner 2/23/2022
这在实际的 HTTP 规范中被调用。即使您设法发送带有正文的(格式错误的)GET,也不需要服务器来支持它。如果有任何 API 需要 GET 上的正文,则该 API 超出了规范,而不是客户端。
0赞 Matt 2/23/2022
@Sujoy它不是一个有问题的客户端,这就是所有 Http 请求的工作方式,并且已经做了很长时间。如果要通过 GET 请求发送数据,则需要采用路由数据、查询字符串或标头的形式,但不能采用正文内容

答:

-1赞 Serge 2/23/2022 #1

修复操作,你不能用get发送正文数据,看这篇文章 HTTP GET with request body

[HttpPost("GetCentralPath")]
public async Task<IActionResult> GetCentralPath(LicenseMachineValidateRequestDTO dto)

并修复请求,将 Method = HttpMethod.Get 替换为 Post,这就是生成错误的原因

var request = new HttpRequestMessage
        {
            Method = HttpMethod.Post,
            RequestUri = new Uri($"{Constants.URL.APIBase}licensemachine/GetCentralPath"),
            Content = new StringContent(JsonConvert.SerializeObject(licenseMachine), Encoding.UTF8, "application/json"),
        };

评论

0赞 Sujoy 2/23/2022
我们始终可以使用 GET 发送身体数据,并且端点工作正常。我大摇大摆地测试了它。问题出在客户端上。
0赞 Matt 2/23/2022
Swagger 可能假设 是从查询字符串绑定的,因为它不可能来自正文。LicenseMachineValidateRequest
0赞 Serge 2/23/2022
@Sujoy 如果你不打算遵循答案,你为什么要发布问题?人们因为你而浪费时间。常识应该告诉你这是不可能的,因为 compiller 会产生运行时错误。