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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 22:15:02