c# JSON REST 响应通过 3 种不同的方法(WebRequest、RESTSharp、HttpClient)是空的,但 Postman 和浏览器可以工作

Posted

技术标签:

【中文标题】c# JSON REST 响应通过 3 种不同的方法(WebRequest、RESTSharp、HttpClient)是空的,但 Postman 和浏览器可以工作【英文标题】:c# JSON REST response via 3 different approaches (WebRequest, RESTSharp, HttpClient) is empty, but Postman and browser works 【发布时间】:2021-01-30 21:29:22 【问题描述】:

当在 C# 中调用一个在 Postman(或通过 Firefox)中没有问题的特定端点时,我得到一个空响应。

我调用的 url 正在返回一个数据集合。在 url 参数中,我可以指定我想要多少所述数据。 我检查了 Postman 中的响应大小,当我限制 C# 调用中请求的数据量以使响应约为 700kb 时,我会收到 JSON 响应。

但是,如果我在 C# 调用中超出此大小,则响应为空“”并且返回的 ContentLength = -1(返回的 statusCode 为 200,因此至少看起来没问题)。在 C# 中失败的相同请求在 Postman 和 Firefox 中运行良好,但是......

我怀疑这是因为反序列化器的缓冲区不够大,或者因为响应仍在传输中,并且代码在读取整个响应主体之前以某种方式继续执行...

以下是我测试过的 3 个实现:

1:

var httpClient = new HttpClient();
var responseMessage = await httpClient.GetAsync(requestUrl, HttpCompletionOption.ResponseHeadersRead);
if (responseMessage.StatusCode == System.Net.HttpStatusCode.OK)

      using (var httpStream = await responseMessage.Content.ReadAsStreamAsync())
      
           using (var sr = new StreamReader(httpStream))
           
               Info(await sr.ReadToEndAsync()); //Info logs the string to a file
           
      

2(RESTSharp):

var client = new RestClient();
var request = new RestRequest(requestUrl, Method.GET, DataFormat.Json);
Info(request.Content); //Info logs the string to a file

3:

var httpWebRequest = (HttpWebRequest)WebRequest.Create(requestUrl);
httpWebRequest.ContentType = "application/json; charset-utf8";
var httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse;
var binReader = new BinaryReader(responseStream);
const int bufferSize = 4096;
byte[] responseBytes;
using (MemoryStream ms = new MemoryStream())

   byte[] buffer = new byte[bufferSize];
   int count;
   while ((count = binReader.Read(buffer, 0, buffer.Length)) != 0)
   
         ms.Write(buffer, 0, count);
   
   responseBytes = ms.ToArray();

Info(Encoding.UTF8.GetString(responseBytes, 0, responseBytes.Length)); //Info logs the string to a file

我没有修改 HttpClient.MaxResponseContentBufferSize 属性,但为了更好的衡量,我也尝试更改此值,但无济于事。

我该如何解决这个问题?

【问题讨论】:

Postman 可以将请求导出为 C# 代码。你可以试试那个代码吗? 所有这些方法都在最低级别使用 HttpClient。他们都工作得很好。 700KB 也是一个非常小的文件。此外,您不是说即使在 POSTMAN 中也只能返回 700KB 吗?看起来 service 拒绝了会返回更多数据的请求 发生这种情况时的实际反应是什么?什么是状态码? C# 代码只是忽略失败,它不会记录它们。您可能会收到 400(错误请求) 有一个 HttpClient.MaxResponseContentBufferSize 属性 (docs.microsoft.com/en-us/dotnet/api/… ) 您修改该属性的任何机会 “此外,您不是刚刚说即使在 POSTMAN 中,您最多只能返回 700KB 吗?看起来该服务拒绝返回更多数据的请求”@PanagiotisKanavos 在 Postman 中(或浏览器)无论响应的大小如何,它都可以正常工作。遗憾的是,该问题仅出现在 C# 中... 【参考方案1】:

我找到了问题,它是由我正在连接的后端服务引起的。再次感谢@Panagiotis Kanavos

【讨论】:

以上是关于c# JSON REST 响应通过 3 种不同的方法(WebRequest、RESTSharp、HttpClient)是空的,但 Postman 和浏览器可以工作的主要内容,如果未能解决你的问题,请参考以下文章

在 REST API 中取消转义 json 响应

用于模拟响应的 Python Quick Rest API

如何将带有自定义标头的任意 JSON 数据发送到 REST 服务器?

为啥我的 C# 应用程序在此 REST 请求上失败,但通过浏览器可以正常工作?

Rails 3:在 Rails 中使用 JSON 响应 REST-ful 操作的正确方法是啥?

如何通过 JSONP 或 HTTP 代理访问 Rally REST API 的 JSON 响应?