10

我正在使用HttpClient类与我的 WPF 应用程序中的 Web 服务进行通信。

当我在同一连接上发出连续的 GET 请求时,一切正常。但是,当我在同一连接上发出连续的 PUT/PATCH 请求时,第一个请求准确执行并且我收到响应,但第二个请求不包括请求中的正文,并且我收到臭名昭著的错误“服务器提交了协议违规。Section=ResponseStatusLine"。

如果我在每次请求后通过添加Connection: close来手动关闭连接,我的请求就会成功完成。这种“解决方案”是一种糟糕的模式,性能无法适当扩展。

以下是来自正在发送的请求的我的 TCP 流输出列表的去品牌化版本:

Wireshark:跟随 TCP 流输出

GET /domain/api/tenant/current/object?objectName=Lizbot HTTP/1.1
Accept: application/json

    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    Content-Length: 50
    {"Data":[{"Id":123,"ObjectName":"Lizbot","Date":null}],"Errors":[]}

PATCH /domain/api/tenant/current/object/123 HTTP/1.1
Accept: application/json
Content-Type: application/json; charset=utf-8
Content-Length: 50
{"Id":123,"ObjectName":"Lizbot","Date":null}

    HTTP/1.1 204 No Content
    Content-Type: application/json; charset=utf-8
    {"Data":null,"Errors":[]}

PATCH /domain/api/tenant/current/object/123/otherObject HTTP/1.1
Accept: application/json
Content-Type: application/json; charset=utf-8

    HTTP/1.1 400 Bad Request</b>
    Content-Type: text/html; charset=us-ascii
    Connection: close
    Content-Length: 311

请注意,第二个 PATCH 缺少它应该修补的对象。如果我更改 PATCHing 的顺序,第二个 PATCH 仍然缺少它的对象。

这个错误似乎在我尝试过的一些已知解决方案中很常见。它们包含此解决方案,其中涉及在 Web.Config 中将 useUnsafeHeaderParsing 属性设置为TRUE并将 Keep-Alive 属性设置为FALSE。我还尝试了以这种方式设置这些属性的解决方案,如下所示:

 ServicePointManager.DefaultConnectionLimit = 2;
 ServicePointManager.Expect100Continue = false;

这些解决方案都没有奏效。需要注意的是,当使用 Http Debugging 代理工具 Fiddler 来捕获这些请求时,我没有收到任何错误。

所以我要问的是,是否有人知道缓解这个错误的好方法,这样我就可以在一个连接中发出多个请求而不会丢失更新的主体。如果需要更多细节,我很乐意提供。

4

2 回答 2

10

经过大量调试和阅读,我意识到我正在尝试编辑 WPF 应用程序的 Web.Config 文件而不是 app.config 文件!

因此,如果您将此代码放在WPF 应用程序的配置标记根目录的app.config文件中,它可以解决问题。

<system.net>
<settings>
<httpWebRequest useUnsafeHeaderParsing = "true"/>
</settings>
</system.net>
于 2013-08-28T19:18:39.417 回答
6

根本问题是 PATCH 响应包含响应正文中的内容。确保服务器在发送 204 No Content 时不发送内容。

于 2013-08-28T21:03:21.943 回答