C#中HTTP请求发送多文件遇大文件报错(contentLength < 0)求助
大文件上传报错(contentLength < 0)的解决方法
问题描述
我正在开发一款即时通讯类应用,尝试为消息添加附件功能。目前将所有文件存入ObservableCollection,通过创建MultipartFormDataContent添加文件、设置请求头后发送。代码如下:
private void _SendFile(string ShortUrl, ObservableCollection<LastFilesModel> files) { try { var url = IpAddress_server + ShortUrl; client = new HttpClient(); var content = new MultipartFormDataContent(); content.Headers.ContentType.MediaType = "multipart/form-data"; content.Headers.Add(@"Content-Length", "2147483648"); int count = 0; foreach(var file in files) { count++; var stream = new System.IO.FileStream(file.FullName, System.IO.FileMode.Open, System.IO.FileAccess.Read); stream.Position = 0; content.Add(new StreamContent(stream), "file_"+ count, file.ShortName); } var httpMethod = HttpMethod.Post; var request = new HttpRequestMessage() { RequestUri = new Uri(url), Method = httpMethod, Content = content, }; request.Headers.Add("Authorization", "Bearer " + MyUser.Token); var response = client.SendAsync(request).Result; response.EnsureSuccessStatusCode(); } catch(Exception ex) { var s =ex.Message; } }
发送单个文件或多个小文件时一切正常,但发送33MB这类大文件时,出现错误:
One or more errors occurred. (contentLength < 0)
解决方案
1. 删除手动设置的Content-Length头
你手动添加了固定值的Content-Length头,而MultipartFormDataContent会自动计算并设置正确的内容长度。当文件总大小超过你设置的固定值,或者计算过程中出现冲突时,就会触发contentLength < 0的错误。直接删除这行代码:
content.Headers.Add(@"Content-Length", "2147483648");
2. 复用HttpClient实例
每次调用方法都新建HttpClient实例可能导致连接泄漏,建议将其声明为类的静态成员,复用实例:
private static readonly HttpClient _client = new HttpClient();
3. 优化异步调用方式
使用.Result阻塞异步操作容易引发死锁或异常,将方法改为异步并使用await,同时用using确保文件流资源释放:
private async Task _SendFile(string ShortUrl, ObservableCollection<LastFilesModel> files) { try { var url = IpAddress_server + ShortUrl; var content = new MultipartFormDataContent(); int count = 0; foreach(var file in files) { count++; using var stream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read); content.Add(new StreamContent(stream), $"file_{count}", file.ShortName); } var request = new HttpRequestMessage(HttpMethod.Post, url) { Content = content }; request.Headers.Add("Authorization", $"Bearer {MyUser.Token}"); var response = await _client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); response.EnsureSuccessStatusCode(); } catch(Exception ex) { var errorMsg = ex.Message; // 这里可以添加错误日志或用户提示逻辑 } }
4. 大文件上传额外优化
- 启用分块传输,避免一次性加载整个文件到内存:
content.Headers.TransferEncodingChunked = true; - 调整超时时间,适配大文件上传时长:
_client.Timeout = TimeSpan.FromMinutes(10);
内容的提问来源于stack exchange,提问作者Katya Appazova
相关产品推荐
相关产品推荐

