如何为RestSharp文件上传请求添加Content-Md5 Header解决AWS S3 BadDigest错误
AWS S3预签名URL上传BadDigest问题(RestSharp vs HttpClient)
我尝试将字符串列表以CSV格式上传至AWS S3的预签名URL,使用.NET默认HttpClient已成功实现,但使用RestSharp RestClient时失败,AWS返回错误:BadDigest - 您指定的Content-MD5与我们收到的不匹配。
输入参数说明:
ids:字符串列表md5:通过System.Security.Cryptography库的md5.ComputeHash()计算得到的byte[]url:预签名URL
成功的HttpClient代码
using (var ms = new MemoryStream()) { using (var sw = new StreamWriter(ms, new UTF8Encoding(false), 8192, true)) { sw.Write(string.Join(Environment.NewLine, ids)); } ms.Position = 0; var file = ms.ToArray(); var content = new ByteArrayContent(file); content.Headers.ContentType = new MediaTypeHeaderValue("text/csv"); content.Headers.ContentLength = file.Length; content.Headers.ContentMD5 = md5; var client = new HttpClient(); var result = client.PutAsync(url, content).Result; var response = result.Content.ReadAsString(); }
失败的RestSharp代码
using (var ms = new MemoryStream()) { using (var sw = new StreamWriter(ms, new UTF8Encoding(false), 8192, true)) { sw.Write(string.Join(Environment.NewLine, ids)); } ms.Position = 0; var file = ms.ToArray(); var md5Based64 = Convert.ToBase64String(md5).Replace("-", ""); var options = new FileParameterOptions { DisableFilenameEncoding = true, }; var uploadRequest = new RestRequest() .AddFile("", file, "", "text/csv", options) .AddOrUpdateHeader("Content-Md5", md5Based64) .AddOrUpdateHeader("Content-Length", file.Length) .AddOrUpdateHeader("Content-Type", "text/csv"); var restClient = new RestClient( new Uri(url), configureSerialization: cfg => { cfg.UseNewtonsoftJson(); }, useClientFactory: true ); var response = restClient.ExecuteAsync(uploadRequest, Method.Put).Result; }
修复建议及代码
问题根源
AddFile会将请求体包装为multipart/form-data格式,与你计算MD5的纯CSV内容不符- 多余的
.Replace("-", "")操作破坏了正确的MD5 Base64值 - 手动设置
Content-Length和Content-Type会与RestSharp自动处理的内容冲突
修复后的代码
using (var ms = new MemoryStream()) { using (var sw = new StreamWriter(ms, new UTF8Encoding(false), 8192, true)) { sw.Write(string.Join(Environment.NewLine, ids)); } ms.Position = 0; var file = ms.ToArray(); var md5Base64 = Convert.ToBase64String(md5); // 移除不必要的替换操作 var uploadRequest = new RestRequest(Method.Put) .AddBody(file, "text/csv") // 直接上传纯字节数组,指定内容类型 .AddOrUpdateHeader("Content-Md5", md5Base64); // 仅保留正确的MD5 Header var restClient = new RestClient(new Uri(url), configureSerialization: cfg => { cfg.UseNewtonsoftJson(); }, useClientFactory: true); var response = restClient.ExecuteAsync(uploadRequest).Result; }
内容的提问来源于stack exchange,提问作者mdng
相关产品推荐
相关产品推荐

