C#: HttpClient, 服务器提交了一个协议违规的错误。Section=ResponseStatusLine

10

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

当我在同一连接上进行连续的GET请求时,一切正常。但是,当我在同一连接上进行连续的PUT/PATCH请求时,第一个请求执行得很准确,我收到响应,但第二个请求不包括请求主体,我收到了“服务器提交了协议违规。部分=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 缺少它应该修补的对象。如果我改变 PATCH 的顺序,第二个 PATCH 仍然缺少它的对象。

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

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

所有这些解决方案都无法解决问题。需要注意的是,当使用 HTTP 调试代理工具 Fiddler 来捕获这些请求时,我没有收到任何错误信息。

因此,我的问题是是否有人知道一个好的解决方案来缓解这个错误,以便我可以在一个连接中进行多个请求而不会丢失更新的主体内容。如果需要更多细节,我很乐意提供。

2个回答

10

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

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

<system.net>
<settings>
<httpWebRequest useUnsafeHeaderParsing = "true"/>
</settings>
</system.net>

6
根本问题在于PATCH响应在响应体内包含内容。确保服务器在发送204 No Content时不发送内容。

谢谢!我接受这个答案,虽然我的方法可以避免抛出错误,但这确保了我不会有错误需要抛出。 - Liz Miner
1
虽然我同意发送带有主体的204是一种协议违规,但HttpClient可以毫无问题地处理这种情况。自托管Web API也可以。也许是IIS搞砸了事情。 - Darrel Miller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接