使用 C#的HttpClient 进行表单提交 问题记录
在C# 中 使用 MultipartFormDataContent 类型 构建表单请求.
按照文档提交之后,一直提示参数错误。差异看下图
浏览器抓包
不是真的浏览器抓包(C#模拟的),所以下面name=“id” 没有双引号, 抓包的时候忘记还原了
C#抓包
解决方法
1. Boundary 的双引号
使用 MultipartFormDataContent 提交的表单请求,外部 Content-Type 的 boundary 值带有 " 号。而 Postman 提交的表单请求,它的 boudary 值是没有双引号的。
使用如下代码解决
var postContent = new MultipartFormDataContent
var boundaryValue = postContent.Headers.ContentType.Parameters.Single(p => p.Name == "boundary");
boundaryValue.Value = boundaryValue.Value.Replace("\"", String.Empty);
2. 表单内键值对,值的双引号
第二个问题则是表单内的内容,他们的 name 键值对,其值又没有双引号,所以你得在添加 Content 的时候,得手动指定双引号。
var postContent = new MultipartFormDataContent
{
{ new StringContent(id), @"""id""" },
{ filestream, @"""file""", @"""blob""" },
{ new StringContent(index.ToString()), @"""partNum""" }
};
3. 表单字段 缺少 Content-Type application/octet-stream
var filestream = new ByteArrayContent(heByte);
filestream.Headers.Add("Content-Type", "application/octet-stream");
//Content-Disposition: form-data; name="file"; filename="blob"
filestream.Headers.Add("Content-Disposition", @"form-data; name=""file""; filename=""blob""");
3. 完整文件分片上传代码
string FileName = "C:\\Users\\xzf\\Desktop\\1.zip";
FileStream file = new FileStream(FileName, FileMode.Open, FileAccess.Read);
int SplitSize = 5242880;//5M分片长度
int index = 1; //序号 第几片
long StartPosition = 5242880 * (index - 1);
long 剩余长度 = file.Length - StartPosition;//真不知道怎么起命了,就这样吧
if (剩余长度 < 5242880)
{
SplitSize = 剩余长度;
}
byte[] heByte = new byte[SplitSize];
file.Seek(StartPosition, SeekOrigin.Begin);
//第一个参数是 起始位置
file.Read(heByte, 0, SplitSize);
//第三个参数是 读取长度(剩余长度)
file.Close();
var filestream = new ByteArrayContent(heByte);
filestream.Headers.Add("Content-Type", "application/octet-stream");
//Content-Disposition: form-data; name="file"; filename="blob"
filestream.Headers.Add("Content-Disposition", @"form-data; name=""file""; filename=""blob""");
var postContent = new MultipartFormDataContent
{
{ new StringContent(id), @""id""" },
{ a, @"""file""", @"""blob""" },
{ new StringContent(index.ToString()), @"""partNum""" }
};
var boundaryValue = postContent.Headers.ContentType.Parameters.Single(p => p.Name == "boundary");
boundaryValue.Value = boundaryValue.Value.Replace("\"", String.Empty);
var res = httpClient.PostAsync(url, postContent);