C#无需Multipart form data向AWS S3存储桶及预签名URL上传文件的方法
问题修复方案
核心错误原因
- 你使用了
MultipartFormDataContent封装请求内容,而预签名PUT接口要求请求体直接为文件二进制数据,不支持multipart表单格式的封装数据 - 代码中仅初始化了与文件长度匹配的空字节数组,未将文件流内容读取到数组中,实际上传的是空内容
- 预签名URL本身已携带所有鉴权参数,不需要手动在请求头添加
AWSAccessKeyId、Signature、x-amz-security-token这类鉴权字段,重复添加会触发鉴权失败 - 每次请求实例化新的
HttpClient会造成套接字资源浪费,长期运行会触发端口耗尽问题
修正后代码
// 建议将HttpClient设为单例,或通过IHttpClientFactory获取,避免重复实例化 private static readonly HttpClient _httpClient = new HttpClient(); public async Task<string> UploadFile(string filePath, string mediaUploadURL, string mediaId, string fileName, string systemTag, string customUserAgent, string tagging) { // 直接读取文件流作为请求内容,大文件上传无需转存字节数组,更节省内存 using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); using var fileContent = new StreamContent(fileStream); // 可根据文件后缀动态调整ContentType,比如图片传image/jpeg、音频传audio/mpeg fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("video/mp4"); // 仅添加自定义元数据、UA、标签类非鉴权请求头 fileContent.Headers.Add("x-amz-meta-media_id", mediaId); fileContent.Headers.Add("x-amz-meta-name", fileName); fileContent.Headers.Add("x-amz-meta-system", systemTag); _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(customUserAgent); fileContent.Headers.Add("x-amz-tagging", tagging); // 直接传入文件内容作为请求体,不使用MultipartFormDataContent封装 var response = await _httpClient.PutAsync(mediaUploadURL, fileContent); response.EnsureSuccessStatusCode(); var responseContent = await response.Content.ReadAsStringAsync(); return responseContent; }
补充说明
如果上传的是超过100M的大文件,建议对接对象存储的分片上传能力,预签名URL同样支持分片上传的场景,可大幅提升上传成功率和断点续传能力。
内容的提问来源于stack exchange,提问作者Adore96
相关产品推荐
相关产品推荐

