当前位置: 首页 > 知识库问答 >
问题:

http request exception——这是客户端还是服务器的问题?

公孙河
2023-03-14

不久前,我使用HttpClient类实现了一些代码来使用REST Api。

using (var client = new HttpClient() { BaseAddress = new Uri(@"https://thirdparty.com") })
{
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(...);

    var uri = new Uri(@"rest/api/foo", UriKind.Relative);
    var content = new StringContent(json.ToString());

    using (var response = await client.PostAsync(uri, content))
    {
        // etc ...
    }
}

这段代码似乎在测试和生产环境(每个环境访问一个测试/生产 URI)下都非常有效。最近,我们开始仅在生产环境中获得 HttpRequestException:System.Net.Http.HttpRequestException:将内容复制到流时出错。

这似乎有点奇怪,所以我用Postman发送相同的消息,它工作得很好。我不确定为什么我们的代码失败了,而邮递员却在工作。我更改了json数据中的一个参数(状态从“NY”变为“NV”)和我们的。NET代码运行良好——当然我们不能只是发送错误的json数据,所以这不是一个解决方案;这更像是观察到完全相同的代码在不同的内容下工作良好。

有趣的是,我们可以进行两个代码更改来解决这个问题。首先,Postman能够使用ResSharp包生成工作的C#代码。或者,我从另一个指向使用HttpVersion 1.0的问题中找到了答案:

using (var request = new HttpRequestMessage(HttpMethod.Post, uri))
{
    request.Version = HttpVersion.Version10;
    request.Content = new StringContent(json.ToString());

    using (var response = await client.SendAsync(request))
    {
        // etc ...
    }
}

令人困惑的是Postman使用HTTP / 1.1版本。所以,总结一下:

  • 如果我们更改json数据(美国州从“NY”更改为“NV”),代码有效。
  • 相同的json和代码对测试uri有效。
  • 更改代码以使用ResSharp包有效。
  • 将代码更改为使用HTTP/1.0而不是HTTP/1.1有效。

为什么Postman能够使用HTTP/1.1工作,但Http客户端失败?这是我们客户端的问题吗(代码适用于美国其他州)?这是. NET Framework中的错误吗?第三方REST Api的实现/托管有问题吗?

邮递员标题:

POST rest/api/foo HTTP/1.1
Host: thirdparty.com
Content-Type: application/json
Authorization: Basic SOME_ENCRYPTED_USER_PASS
Cache-Control: no-cache
Postman-Token: 2fa5b5a0-b5d3-bd4c-40f0-d2b55b60316b

示例Json:

{
    "stateCode": "NY",
    "packageID": "58330",
    "name": "58330-PRI-1",
    "documents": [
        {
            "type": "SPECIAL",
            "name": "Sample Document",
            "documentID": "3569976"
        }
    ],
    "descriptions": [
        {
            "city": "New York",
            "state": "NY"
        }
    ]
}

堆栈跟踪:

AggregateException: One or more errors occured.
HttpRequestException: Error while copying content to a stream.
IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
SocketException: An existing connection was forcibly closed by the remote host.

共有2个答案

郑富
2023-03-14

您是否在运行 HttpClient 的计算机上安装了防病毒/防火墙?我过去曾遇到过AVG,Mcafee,Norton和其他默默阻止请求的问题。找出确切的位置非常棘手,但是可能有一个监视端口的选项卡,取消勾选/禁用它可能有助于识别问题。如果是这种情况,正确的解决方案是将您的“thirdparty.com”列入相应供应商的白名单。

可能也值得查看服务器上的响应头?你能把它们添加到你的问题中吗?只是因为,过去我发现内容安全策略标头阻止了我的一些请求的完成?

姬向明
2023-03-14

由于您可以稍微更改数据并使其成功,我会说您的问题与您的任何代码无关。如果他们的服务器缓存了一个错误的值,并将继续向您发送该值,直到他们的缓存清除,该怎么办?

尝试隐式告诉服务器不要使用缓存值。。。

using (var client = new HttpClient() { BaseAddress = new Uri(@"https://thirdparty.com") })
{
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(...);

    var uri = new Uri(@"rest/api/foo", UriKind.Relative);
    var content = new StringContent(json.ToString());

    client.DefaultRequestHeaders.CacheControl = CacheControlHeaderValue.Parse("no-cache");

    using (var response = await client.PostAsync(uri, content))
    {
        // etc ...
    }
}

看看是否能得到有效的响应流。

 类似资料:
  • 我正在尝试使用ExpressJS和Coffeescript制作一个网络应用程序,它从亚马逊、LastFM和必应的网络应用程序接口中提取数据。 用户可以从特定乐队请求特定专辑的价格、即将到来的音乐会时间和乐队的位置等数据,等等...诸如此类的东西。 我的问题是:我应该使用和在客户端进行这些API调用,还是应该在服务器端进行?我已经完成了客户端请求;我如何从服务器端进行API调用 我只想知道最佳实践是

  • 我想在一些计算机之间建立点对点连接,这样用户就可以在没有外部服务器的情况下聊天和交换文件。我最初的想法如下: 我在服务器上制作了一个中央服务器插座,所有应用程序都可以连接到该插座。此ServerSocket跟踪已连接的套接字(客户端),并将新连接的客户端的IP和端口提供给所有其他客户端。每个客户端都会创建一个新的ServerSocket,所有客户端都可以连接到它。 换句话说:每个客户端都有一个Se

  • 我最近对尝试将我的石头-纸-剪刀游戏改编成一个多人友好的程序感兴趣,所以今天我决定查阅一个关于服务器的教程。似乎我正在精确地跟踪它(除了使用不同的IDE之外)。然而,有些地方出了问题,我不确定到底是什么,它对教程制造商来说很好。我查过EOFException,但并没有帮到我。 Youtube上的教程 [关于EOFException的文档](我在这里有一个链接,但我需要至少10个声誉才能发布两个以上

  • 我收到了一个新的密钥库。jks文件用于ssl连接,以替换旧的但仍在工作的。jks密钥库文件,但我收到了“意外握手消息:serve_hello”错误。我被告知要确保密钥库包含客户端证书,所以我使用keytool将其证书导出到pem文件,然后使用openssl检查目的。结果显示 证书用途:SSL客户端:否SSL客户端CA:否SSL服务器:是SSL服务器CA:否... 然而,当我应用相同的过程来检查旧的

  • 前面的章节介绍了所有 Redis 的重要功能组件: 数据结构、数据类型、事务、Lua 环境、事件处理、数据库、持久化, 等等, 但是我们还没有对 Redis 服务器本身做任何介绍。 不过, 服务器本身并没有多少需要介绍的新东西, 因为服务器除了维持服务器状态之外, 最重要的就是将前面介绍过的各个功能模块组合起来, 而这些功能模块在前面的章节里已经介绍过了, 所以本章将焦点放在服务器的初始化过程,

  • 问题内容: 我正在构建同构应用程序,但是我正在使用仅在客户端上呈现的第三方组件。因此,特别是对于此组件,仅在客户端渲染时才需要渲染。 如何检测我是在客户端还是在服务器上?我正在寻找类似或的东西。 问题答案: 在内部,React使用一个为此调用的实用程序。它实现了一些有用的属性,例如和。该解决方案本质上只是此处所建议的。 实施 我这样在我的应用程序中使用 编辑 这是一个未记录的功能,不应直接使用。它