c# - HttpRequestException——这是客户端或服务器问题吗?

标签 c# json rest dotnet-httpclient postman

不久前,我使用 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 来发送相同的消息并且效果很好。我不确定为什么我们的代码会失败而 Postman 却能正常工作。我更改了 json 数据中的一个参数(状态从“NY”到“NV”),我们的 .NET 代码工作正常——当然我们不能只发送错误的 json 数据,所以这不是解决方案;这更像是一个观察结果,即完全相同的代码可以很好地处理不同的内容。


有趣的是,我们可以更改两个代码来解决这个问题。首先,Postman 能够使用 RestSharp 生成有效的 C# 代码。包裹。或者,我找到了一个 answer来自另一个指向使用 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。
  • 更改代码以使用 RestSharp 包有效。
  • 更改代码以使用 HTTP/1.0 而不是 HTTP/1.1 是可行的。

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


postman 标题:

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.

最佳答案

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

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

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 ...
    }
}

并查看您是否获得了有效的响应流。

关于c# - HttpRequestException——这是客户端或服务器问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38615482/

相关文章:

javascript - 将 javascript 数组加载到 Chartist.js 作为系列

java - 扩展谷歌库方法的最佳方式

c# - 值 '\r\n' 的格式无效 .","ExceptionType":"System. FormatException

java - 无法从 Servlet 在本地文件系统上找到文件

c# - 如何将 1D 字节数组转换为保存位图的 2D 字节数组?

c# - 外键约束解释问题

c# - 从合约访问端点配置

c# - 如何在不使用 HttpContext 的情况下获取 Web 应用程序的当前配置?

javascript - JS中如何将json转为树形数组?

java - 添加指向 REST 响应的链接