3

我正在尝试使用 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);
}

然后是尝试调用这些方法的客户端代码。POST 请求如下所示:

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

1 回答 1

5

ToJsonContent你写的功能吗?如果是这样,可能值得一看,以确保您提供了正确的 Content-Type 并生成了正确的 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 我application/json作为参数提供。我知道如果 Web API 不知道您的请求是什么媒体类型,它会做一些疯狂的事情。您的 RestClient 测试确实有效的事实让我认为您发送的 JSON 无效。

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

于 2012-05-17T20:24:32.073 回答