c# - HttpClient.SendAsync 不发送请求正文

标签 c# json asp.net-web-api http-delete

我正在使用 .NET 4.0 的 ASP.NET Web API 客户端库(Microsoft.AspNet.WebApi.Client 版本 4.0.30506.0)。

我需要发送带有请求正文的 HTTP DELETE。我将其编码如下:

using (var client = new HttpClient())
{
    client.BaseAddress = Uri;
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    // I would normally use httpClient.DeleteAsync but I can't because I need to set content on the request.
    // For this reason I use httpClient.SendAsync where I can both specify the HTTP DELETE with a request body.
    var request = new HttpRequestMessage(HttpMethod.Delete, string.Format("myresource/{0}", sessionId))
      {
        var data = new Dictionary<string, object> {{"some-key", "some-value"}};
        Content = new ObjectContent<IDictionary<string, object>>(data, new JsonMediaTypeFormatter())
      };
    var response = await client.SendAsync(request);
    // code elided
}

对于 Fiddler,请求主体永远不会序列化:

删除 http://localhost:8888/myApp/sessions/blabla123 HTTP/1.1 接受:应用程序/json 内容类型:application/json;字符集=utf-8 主机:本地主机:8888 内容长度:38 期望:100-继续

服务器响应:

HTTP/1.1 408 请求正文不完整 日期:2014 年 8 月 10 日星期日 17:55:17 GMT 内容类型:文本/html;字符集=UTF-8 连接:关闭 缓存控制:无缓存,必须重新验证 时间戳:13:55:17.256 请求正文不包含指定的字节数。得到 0,预计 38

我尝试了一些变通方法,包括将序列化的类型更改为其他类型、使用 JsonSerialize 自己进行序列化、将 HTTP DELETE 更改为 PUT 等...

没有任何效果。任何帮助将不胜感激。

最佳答案

我解决了这个问题,尽管它没有任何意义。我注意到,如果我将调用更改为 HTTP PUT 或 POST,它仍然无法将内容序列化为请求正文。这很奇怪,因为以前的 PUT 和 POST 是成功的。在对框架库进行大量调试(使用 Reflector)之后,我终于找到了唯一“不同”的地方。

我正在使用 NUnit 2.6.2。我的测试结构是:

[Test]
async public void Test()
{
  // successful HTTP POST and PUT calls here
  // successful HTTP DELETE with request body here (after 
  //       moving it from the TearDown below)
}

[TearDown]
async public void TerminateSession()
{
  // failed HTTP DELETE with request body here
}

为什么这在 TearDown 中失败但在测试本身中却没有?我不知道。 TearDown 属性或使用 async 关键字(因为我等待异步调用)是否有问题?

我不确定是什么导致了这种行为,但我现在知道我可以提交带有请求正文的 HTTP DELETE(如我在问题中的代码示例中所述)。

另一种有效的解决方案如下:

[Test]
async public void Test()
{
  // create and use an HttpClient here, doing POSTs, PUTs, and GETs
}

// Notice the removal of the async keyword since now using Wait() in method body
[TearDown]
public void TerminateSession()
{
  // create and use an HttpClient here and use Wait().
  httpClient.SendAsync(httpRequestMessage).Wait();
}

关于c# - HttpClient.SendAsync 不发送请求正文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25231548/

相关文章:

c# - 使用 Task<bool> 返回类型对异步方法进行单元测试

c# - 如何在代码中为 DataTemplate 分配事件处理程序?

c# - LINQ 到 SQL : Alter Table or Add New Table to Existing Database

访问 asp.net Web API 时 android 中的 java.net.MalformedURLException

c# - 需要调试从客户端计算机请求的 Web API 服务 - 需要帮助,我该怎么做?

c# - SendKeys.Send 函数不起作用

javascript - 如何在 three.js 中导入 json 和渲染

javascript - 如何保存ArrayBuffer?

json - "Not JSON compliant number"构建geojson文件

asp.net mvc 和 web api 哪个更好 Http POST 或 PUT