C# HttpClient POST 同时上传参数与文件的实现方法
在 C# 开发中,经常遇到需要通过 HTTP POST 请求同时发送普通表单字段和文件的需求。本文将演示如何利用 HttpClient 结合 MultipartFormDataContent 类,在一个请求体中混合传递键值对参数与文件流,并包含处理 Cookie 和异常状态的完整示例。
基础实现:键值对与字节数组组合
最直观的方式是构建 MultipartFormDataContent 对象,遍历传入的参数集合,将每个字符串参数封装为 StringContent 后加入;随后读取本地文件为字节数组,使用 ByteArrayContent 添加文件部分。最后发起异步 POST 请求。
using (var client = new HttpClient())
{
using (var multipartFormDataContent = new MultipartFormDataContent())
{
// 1. 准备表单参数集合
var values = new[]
{
new KeyValuePair<string, string>("c", "3"),
new KeyValuePair<string, string>("c", "2"),
new KeyValuePair<string, string>("d", "2")
};
// 2. 将参数逐个添加到表单内容中
foreach (var keyValuePair in values)
{
// 注意 Key 需要用双引号包裹以符合 HTTP 规范解析习惯
multipartFormDataContent.Add(new StringContent(keyValuePair.Value),
String.Format("\"{0}\"", keyValuePair.Key));
}
// 3. 添加文件部分(此处以本地图片为例)
multipartFormDataContent.Add(new ByteArrayContent(System.IO.File.ReadAllBytes(@"D:\test.jpg")),
"\"pic\"",
"\"test.jpg\"");
// 4. 执行 POST 请求
var requestUri = "http://localhost:8080";
// Result 属性用于同步等待异步操作完成,生产环境建议 await
var html = client.PostAsync(requestUri, multipartFormDataContent).Result.Content.ReadAsStringAsync().Result;
}
}进阶示例:含 Header 设置与 Stream 流的上传
在实际业务场景中,上传可能还需要携带自定义 Header(如 Token、Client ID)并处理 JSON 数据串。以下示例展示了如何手动配置边界符、设置 Cookie 以及使用 FileStream 进行文件上传,从而减少内存占用。
- 初始化客户端与请求 URL:根据需要决定是否禁用自动 Cookie 处理以便手动控制,并拼接 RPC 或 API 地址。
- 配置多部分表单头:生成唯一的 Boundary 字符串,显式指定 Content-Type,并注入认证信息等自定义 Header。
- 构建请求主体:验证文件路径有效性,打开文件流并封装为
StreamContent添加到表单中;同时将序列化的 DTO 对象作为普通字符串字段加入。 - 执行与响应处理:调用
PostAsync获取响应,检查状态码并读取返回结果,最后在 Finally 块中安全释放资源。
string reqUrl = JsonrpcHttpClient.MakeRpcUrl(typeof(Wfm_SimReport).Name, "save");
// UseCookies = false 允许手动管理 Cookie 行为
using (HttpClient client = new HttpClient(new HttpClientHandler() { UseCookies = false }))
{
string boundary = string.Format("----WebKitFormBoundary{0}", DateTime.Now.Ticks.ToString("x"));
MultipartFormDataContent content = new MultipartFormDataContent(boundary);
// 设置请求参数头部
content.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
content.Headers.Add("Cookie", TokenManager.Token);
content.Headers.Add("client", "true");
if (string.IsNullOrEmpty(fullPath) && !File.Exists(fullPath))
{
return false;
}
string fileName = Path.GetFileName(fullPath);
// 使用 FileStream 读取文件,更节省内存
FileStream fStream = File.Open(fullPath, FileMode.Open, FileAccess.Read);
content.Add(new StreamContent(fStream, (int)fStream.Length), "file", fileName);
// 添加其他 JSON 字符串参数
content.Add(new StringContent(JsonHelper.Serialize(entity)), "dtoStr");
try
{
var result = client.PostAsync(reqUrl, content).Result;
if (result.IsSuccessStatusCode)
{
string rslt = result.Content.ReadAsStringAsync().Result;
Debug.WriteLine(rslt);
return true;
}
}
catch (Exception ex)
{
Debug.WriteLine(string.Format("获取服务器返回结果错误:消息:{0},堆栈:{1}",ex.Message,ex.StackTrace));
}
finally
{
// 确保文件流和客户端被正确关闭
fStream.Close();
client.Dispose();
}
}总结
通过组合 StringContent、ByteArrayContent 或 StreamContent,开发者可以灵活地在 C# 的 HttpClient 请求中嵌入文件与普通表单数据。关键在于正确设置 MultipartFormDataContent 的边界标识,并注意在异步编程模型下合理处理资源释放与异常捕获。
以上就是 C# HttpClient Post参数同时上传文件的详细内容,更多关于 C# HTTP请求开发技巧的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









