C#使用HttpClient阿里云直传失败解决方案

在C#里,使用HttpClient配合MultipartFormDataContent直传文件,遇到The body of your POST request is not well-formed multipart/form-data异常的处理办法

在使用HttpClient直传时,遇到传输body阿里云不认的情况,经过仔细比对,发现以下几个差异:

1、在Http Header中Content-Type中,boundary需要不带双引号

2、在Form中,每个Form的name值需要用双引号引起来

3、如果文件表单域带有Content-TypeHeader,则该字段需要放在Content-Disposition字段后

4、文件表单域在Content-Disposition中需要带有fileName

5、文件表单域Content-Disposition不支持filename*=utf-8''%22aaa.txt%22这样的文件名表示

阿里云的文档说,表单域name大小写敏感,实际上没有!
我的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public async Task UploadFile(string path, UploadFileData uploadFileData)
{
var fileName = Path.GetFileName(path);
var multipartForm = new MultipartFormDataContent($"-----{Guid.NewGuid().ToString()}");
var streamContent = new StreamContent(File.OpenRead(path));
multipartForm.Add(new ByteArrayContent(Encoding.UTF8.GetBytes(uploadFileData.AccessKey)), "\"OSSAccessKeyId\"");
multipartForm.Add(new ByteArrayContent(Encoding.UTF8.GetBytes(uploadFileData.Key)), "\"Key\"");
multipartForm.Add(new ByteArrayContent(Encoding.UTF8.GetBytes(uploadFileData.Policy)), "\"Policy\"");
multipartForm.Add(new ByteArrayContent(Encoding.UTF8.GetBytes(uploadFileData.Sign)), "\"Signature\"");
multipartForm.Add(streamContent, "\"file\"",$"\"{fileName}\"");

//修饰boundary,移除双引号
var boundary = multipartForm.Headers.ContentType.Parameters.First(o => o.Name == "boundary");
boundary.Value = boundary.Value.Replace("\"", String.Empty);

//修饰文件表单域,移除FileNameStar
streamContent.Headers.ContentDisposition.FileNameStar = null;
var rsp = await this._httpClient.PostAsync(uploadFileData.Url, multipartForm);
var content = await rsp.Content.ReadAsStringAsync();
}

我真的不理解,阿里云OSS到底用了什么技术来解析Mutipart/Form表单,导致标准支持如此落后,如此死板。你们的996福报都用来干啥了?

我的微信公众号
我的公众号