C#使用HttpClient上传文件(multipart表单)

6,455 阅读3分钟

有时候需要使用C#发送网络请求,其中上传文件其实也是使用POST请求。方式也有很多,除了自己组装数据之外,还可以使用HttpClient发送。

上传文件使用HttpClient类其实可以很简单的实现。

1,实例化MultipartFormDataContent类组装表单

在C#中,MultipartFormDataContent类是一个专门用于存放multipart表单数据的类,通过其Add方法可以将表单数据加进去。

假设这里有个上传文件的接口如下:

地址:/upload

方法:POST

参数:

字段类型描述
nameString名字
fileFile文件

也就是说,表单项有一个字符串类型字段,和一个文件,这个时候在C#组装表单如下:

// 读取文件
Stream fileStream = new FileStream(@"C:\Users\swsk33\Pictures\wallpaper-2x\gz-3.png", FileMode.Open, FileAccess.Read);
// 实例化multipart表单模型
var formData = new MultipartFormDataContent();
// 设定文本类型表单项,使用StringContent存放字符串
formData.Add(new StringContent("测试图片"), "name");
// 设定文件类型表单项,使用StreamContent存放文件流
formData.Add(new StreamContent(fileStream), "file", "a.png");

可见MultipartFormDataContent的方法Add可以把我们的表单项加进去,上面第一个Add中第一个参数是StringContent类型,用于存放字符串,第二个参数为接口要求的字段。

第二个Add参数中有三个参数,第一个为StreamContent,存放待上传的文件流,可以看到可以先用FileStream读取文件为文件流再存入,第二个参数为接口要求的字段,第三个参数为文件名,可以自己起,但是扩展名最好是和原来保持一致。

添加文件除了直接放入文件流之外,还可以先读取为字节数据存入,效果一样:

Stream fileStream = new FileStream(@"C:\Users\swsk33\Pictures\wallpaper-2x\gz-3.png", FileMode.Open, FileAccess.Read);
byte[] data = new byte[fileStream.Length];
fileStream.Read(data, 0, data.Length);
fileStream.Close();
formData.Add(new ByteArrayContent(data), key, "gz-3.png");

这样,表单就组装完毕了!

2,实例化HttpClient发送请求

这个就很简单了:

// 实例化HttpClient
HttpClient client = new HttpClient();
// 发送请求
HttpResponseMessage result = client.PostAsync("http://127.0.0.1:8806/upload", formData).Result;
// 接受结果
string responseResult = result.Content.ReadAsStringAsync().Result;
// 打印结果
Console.WriteLine(responseResult);
client.Dispose();
fileStream.Close();

HttpClient有一个PostAsync方法表示发送POST请求,第一个参数为请求地址,第二个为刚刚组装的表单对象,这是一个异步方法,不过向上述一样调用其返回值的Result可以等待其完成,这样会返回一个HttpResponseMessage对象,为响应内容,再调用其ContentReadAsStringAsync方法可以读取响应内容为字符串,这也是异步方法,不过还是向上面一样调用其Result可以等待其完成。

这样就完成了上传文件请求。

3,自定义请求参数

上面的操作其实是一个“简写”,如果需要自定义请求头等等,需要先定义HttpRequestMessage对象(表示一个Http请求)设定其中请求头、请求内容等等,再使用HttpClient发送即可。

// 实例化HttpRequestMessage对象
HttpRequestMessage requestMessage = new HttpRequestMessage();
// 设定请求类型为POST
requestMessage.Method = HttpMethod.Post;
// 设定请求地址
requestMessage.RequestUri = new Uri("http://www.example.com/upload");
// 实例化multipart表单模型
var formData = new MultipartFormDataContent();
// ...省略加入内容至表单的过程...
// 设置请求体为上述multipart表单
requestMessage.Content = formData;
// 设定Content-Type
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
// 加入其他自定义请求头,这里以UA为例,还可以设定其它自定义请求头(注意Content-Type在这里设置是无效的,必须按照上面一行设置)
requestMessage.Headers.TryAddWithoutValidation("User-Agent", "xxx...");

// 实例化HttpClient
HttpClient client = new HttpClient();
// 发送请求
HttpResponseMessage result = client.SendAsync(requestMessage).Result;
// 接受结果
string responseResult = result.Content.ReadAsStringAsync().Result;
// 打印结果
Console.WriteLine(responseResult);

自定义HttpRequestMessage实例之后,使用HttpClientSendAsync方法即可。