PUT 请求导致 400 错误请求

本文关键字:请求 错误 PUT | 更新日期: 2023-09-27 18:34:20

我正在尝试使用HttpClient对Web API方法执行PUT请求。几乎相同的 POST 请求按预期工作,但 PUT 请求会导致 400(错误请求(错误。我不确定我做错了什么。

这是我的 Web API 控制器代码:

public HttpResponseMessage Post(object val)
{
    Debug.WriteLine(val.ToString());
    return new HttpResponseMessage(HttpStatusCode.OK);
}
public HttpResponseMessage Put(int id, object val)
{
    Debug.WriteLine(id.ToString(), val.ToString());
    return new HttpResponseMessage(HttpStatusCode.OK);
}

下面是尝试调用这些方法的客户端代码。开机自检请求如下所示:

var client = new HttpClient();
var content = log.ToJsonContent();
var address = new Uri(_webApiBaseAddress + "logs");
client.PostAsync(address, content).ContinueWith(requestTask =>
    {
        requestTask.Result.EnsureSuccessStatusCode();
    });

不起作用的 PUT 请求如下所示:

var client = new HttpClient();
var content = log.ToJsonContent();
var address = new Uri(_webApiBaseAddress + "logs/" + jobId);
client.PutAsync(address, content).ContinueWith(requestTask =>
    {
        requestTask.Result.EnsureSuccessStatusCode();
    });

如您所见,我已经尽可能简单地剥离了该功能,并且每次我仍然收到PUT请求的错误。

顺便说一下,我可以使用 RestSharp 客户端成功发出 PUT 请求。此代码成功调用 API 方法:

var client = new RestClient(_webApiBaseAddress);
var request = new RestRequest("logs/{id}", Method.PUT);
request.AddUrlSegment("id", jobId.ToString());
request.AddObject(log);
client.Execute(request);

这样做的问题在于,我使用 AddObject 传入的任何对象在到达控制器方法时最终都会变成一个字符串。如果我传入一个 int,我想得到一个 int。HttpClient 使用 POST 方法执行此操作,所以我想使用它,但 PUT 抛出了一个错误。所以我坚持使用 2 个半工作的解决方案,不幸的是,这些解决方案加起来并不是一个完整的解决方案。我将不胜感激对任一模式的反馈,以使其正常工作。

编辑:因为下面提到了,所以这是我.ToJsonContent()扩展方法:

public static StringContent ToJsonContent(this object obj)
{
    var converter = new IsoDateTimeConverter();
    converter.DateTimeStyles = DateTimeStyles.AdjustToUniversal;
    var json = JsonConvert.SerializeObject(obj, converter);
    var content = new StringContent(json, Encoding.UTF8, "application/json");
    return content;
}

PUT 请求导致 400 错误请求

ToJsonContent是你写的功能吗?如果是这样,可能值得一看,以确保您提供正确的内容类型并生成正确的 JSON 格式。要消除JSON的问题,您可以进行如下测试:

var client = new HttpClient();
var content = new StringContent(
    @"{""message"": ""this is a log message"" }",
    Encoding.UTF8,
    "application/json");
var address = new Uri(_webApiBaseAddress + "logs/" + jobId);
client.PutAsync(address, content).ContinueWith(task =>
{
    task.Result.EnsureSuccessStatusCode();
});

Noice I 提供application/json作为参数。我知道 Web API 如果不知道您的请求属于哪种媒体类型,它会做一些疯狂的事情。您的 RestClient 测试确实有效这一事实让我认为您发送的 JSON 无效。

可能对您有所帮助的第二部分是,如果您在控制台应用程序之类的应用程序中对此进行测试,该应用程序可能会在异步调用真正初始化并发送之前关闭,您将不会收到响应。您可以通过在ContinueWith后放置一个.Wait()来测试这一点,但我怀疑如果您实际上得到 400 响应,情况并非如此。