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

ASP.NET Core Web API中HttpClient发送PDF请求超时问题排查

问题描述

我使用Visual Studio的ASP.NET Core Web API项目模板创建了一个支持文件上传的Web API,并编写了处理PDF报告上传的控制器动作方法。

控制器动作代码

[HttpPost("Report/{reportId")]
public async Task<IActionResult> AttachReport(string reportId)
{
    Reporter client = new Reporter();
    await client.AttachReportToRequest(reportId);
    return 
}

请求发送方法代码

public async Task<HttpResponseMessage> AttachReportToRequest(string reportId)
{
    try
    {
        if (authToken is null)
        {
            authToken = await login("username", "passw0rd");
        }
        HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, "/api/to/app/server/reportInfo");
        requestMessage.Headers.Authorization = new AuthenticationHeaderValue("app-JWT", authToken);

        string scanReportFile = $"{Directory.GetCurrentDirectory()}\Reports\sample_report.pdf";
        MultipartFormDataContent requestBody = new MultipartFormDataContent();

        //Create values JSON payload
        requestBody.Add(new StringContent($"\"values\":{{
            \"ReportId\":\"{reportId}\",
            \"Description\":\"test\",
            \"Submitter\":\"John Smith\",
            \"Number of Attachment\":\"1\"
            }}"), "entry");
        
        requestBody.Add(new StreamContent(File.OpenRead("C:/Users/myuser/Documents/ReporterApp/myreport.pdf")), "file-attachment", "C:/Users/myuser/Documents/ReporterApp/myreport.pdf");

        requestMessage.Content = requestBody;
        HttpResponseMessage attachmentResponse = await httpClient.SendAsync(requestMessage);
        return attachmentResponse;
            }
    catch (Exception)
    {

        throw;
    }
}

每次调用HttpClient.SendAsync发送请求都会超时,无法收到服务器响应,但使用Postman调用同一端点、发送相同的multipart/form-data类型请求却能成功。我尝试将文件流放入using块、更换不同文件类型,都无法解决问题,想知道SendAsync请求超时的具体原因是什么?


可能的原因及解决方法

1. JSON格式不完整

你手动拼接的entry字段JSON缺少外层大括号,正确结构应为{"values": {...}},而非仅"values": {...}。服务器解析格式错误的JSON时可能陷入阻塞,导致请求超时。

解决方法:
补全JSON结构,或改用序列化工具避免手动拼接错误:

// 方式1:补全JSON外层大括号
requestBody.Add(new StringContent($"{{
    \"values\":{{
        \"ReportId\":\"{reportId}\",
        \"Description\":\"test\",
        \"Submitter\":\"John Smith\",
        \"Number of Attachment\":\"1\"
    }}
}}"), "entry");

// 方式2:使用JsonSerializer序列化(更可靠)
var payload = new {
    values = new {
        ReportId = reportId,
        Description = "test",
        Submitter = "John Smith",
        NumberOfAttachment = "1"
    }
};
string json = JsonSerializer.Serialize(payload);
requestBody.Add(new StringContent(json, Encoding.UTF8, "application/json"), "entry");

2. 文件参数传递错误

添加文件时,第三个参数传递了完整文件路径,而服务器通常只需要文件名(如myreport.pdf),路径格式可能导致服务器解析异常。

解决方法:
改用Path.GetFileName提取纯文件名:

var filePath = "C:/Users/myuser/Documents/ReporterApp/myreport.pdf";
requestBody.Add(new StreamContent(File.OpenRead(filePath)), "file-attachment", Path.GetFileName(filePath));

3. HttpClient实例管理不当

如果每次调用都新建HttpClient实例,会导致套接字资源耗尽,进而引发超时。Postman因复用连接不会出现此问题。

解决方法:
遵循.NET最佳实践,复用HttpClient实例——比如通过IHttpClientFactory注册为单例,或在应用生命周期内保持同一个实例。

4. 请求内容未指定编码和媒体类型

手动创建的StringContent未指定编码和application/json媒体类型,服务器可能无法正确解析内容,导致处理超时。

解决方法:
创建StringContent时明确指定参数:

new StringContent(json, Encoding.UTF8, "application/json")

5. 控制器代码语法错误

控制器的HttpPost路由模板缺少闭合的},且return语句无返回值,会导致控制器动作执行失败,间接引发服务器无响应超时。

解决方法:
修正控制器代码:

[HttpPost("Report/{reportId}")]
public async Task<IActionResult> AttachReport(string reportId)
{
    Reporter client = new Reporter();
    var response = await client.AttachReportToRequest(reportId);
    return Ok(response.StatusCode); // 根据实际需求返回合适结果
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 20:10:22