You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用HttpClient发送大JSON文件时抛出HttpRequestException问题排查

排查ASP.NET Core 2.2 HttpClient发送大JSON请求失败的问题

结合你遇到的现象——小体积JSON请求正常,800KB以上就抛出「服务器返回无效或无法识别的响应」异常,且Postman测试完全正常,问题大概率出在HttpClient处理大请求/响应的配置或传输方式上,以下是几个针对性的排查和解决方向:

1. 改用StreamContent替代StringContent发送请求

你的代码里用StringContent承载序列化后的JSON,当JSON体积较大时,会把整个字符串加载到内存中,不仅效率低,还可能触发某些底层的缓冲限制,导致请求发送不完整,服务器返回异常响应。换成StreamContent流式传输会更稳定:

public async Task<TResponse> MakeRequest<TRequest, TResponse>(TRequest request) {
    if (request == null) throw new ArgumentNullException(nameof(request));
    
    // 序列化到内存流,避免占用过多内存
    using var ms = new MemoryStream();
    using var writer = new StreamWriter(ms, Encoding.UTF8);
    var serializer = JsonSerializer.CreateDefault();
    serializer.Serialize(writer, request);
    await writer.FlushAsync();
    ms.Position = 0;
    
    var content = new StreamContent(ms);
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    
    var httpRequestMessage = new HttpRequestMessage {
        Method = HttpMethod.Post,
        Content = content
    };
    
    // 先读取响应头,再流式读取响应内容,避免一次性缓冲大响应
    var response = await _httpClient.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseHeadersRead);
    response.EnsureSuccessStatusCode();
    
    // 流式读取响应,避免大字符串加载内存
    using var responseStream = await response.Content.ReadAsStreamAsync();
    using var streamReader = new StreamReader(responseStream);
    using var jsonReader = new JsonTextReader(streamReader);
    var responseObject = JsonSerializer.CreateDefault().Deserialize<TResponse>(jsonReader);
    
    return responseObject ?? throw new InvalidOperationException();
}

2. 延长HttpClient的超时时间

大体积JSON的传输和处理耗时更长,默认HttpClient的超时时间是100秒,如果外部服务处理大请求超过这个时间,可能会导致连接中断,表现为「无效响应」的异常。你可以在注入HttpClient时延长超时:

services.AddHttpClient<IExternalWebServiceProxy, ExternalWebServiceProxy>()
    .ConfigureHttpClient(x => {
        x.MaxResponseContentBufferSize = 1024 * 1000 * 100; // 100MB
        x.Timeout = TimeSpan.FromMinutes(5); // 根据实际情况调整超时时间
    });

3. 明确指定请求内容的编码

你当前创建StringContent时没有指定编码,默认会用UTF-16,但大多数REST服务期望的是UTF-8编码的JSON。编码不匹配可能导致服务器解析请求内容失败,返回异常响应。如果坚持用StringContent,记得明确指定编码:

var jsonString = JsonConvert.SerializeObject(request);
var content = new StringContent(jsonString, Encoding.UTF8, "application/json");

4. 验证服务器Chunked传输编码的兼容性

有些服务器在处理大响应时会启用Chunked传输编码,而ASP.NET Core 2.2的HttpClient在某些场景下对Chunked响应的解析可能存在兼容性问题。你可以尝试在请求头中明确允许Chunked传输:

httpRequestMessage.Headers.TransferEncodingChunked = true;

(前面的流式读取方式已经能很好处理Chunked编码的响应,这个配置可以作为补充尝试)

5. 检查请求Content-Length的正确性

当用StringContent时,它会自动计算Content-Length,但如果序列化后的字符串包含特殊字符或编码转换问题,可能导致Content-Length计算错误,服务器收到的内容不完整,从而返回无效响应。改用StreamContent后,HttpClient会自动处理Content-Length或启用Chunked,能避免这个问题。

内容的提问来源于stack exchange,提问作者Iskander Raimbaev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:14:53