.NET Framework 4.0下不依赖BCL实现multipart/mixed HTTP请求
在.NET Framework 4.0中用HttpWebRequest实现multipart/mixed请求
完全没问题!既然你已经能用HttpWebRequest发送简单请求,只需要扩展它来处理multipart/mixed的格式规则就行——核心就是用边界字符串分隔各个请求部分,并且严格遵循HTTP的格式要求。下面是具体的实现方案:
核心思路
multipart/mixed请求的关键是边界(boundary):
- 在
Content-Type头中指定边界字符串(比如你示例里的batch-1) - 每个请求部分以
--{boundary}开头,后跟该部分的HTTP头(比如Content-Type) - 部分头和内容之间必须留一个空行(
\r\n) - 所有部分结束后,用
--{boundary}--标记请求结束
完整代码实现
我把你的基础代码扩展成了通用的multipart请求方法,还加了辅助类来管理各个请求部分:
using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Text; public class MultipartRequestHelper { public WebResponse SendMultipartRequest(string uri, List<MultipartPart> parts, Dictionary<string, string> customHeaders) { // 定义边界字符串,建议用随机字符串避免和内容冲突,这里用你示例里的batch-1 var boundary = "batch-1"; var request = (HttpWebRequest)WebRequest.Create(uri); request.Method = "POST"; // 设置Content-Type,注意边界要加引号 request.ContentType = $"multipart/mixed; boundary=\"{boundary}\""; // 添加自定义请求头(比如你示例里的Vendor、Product这些) foreach (var header in customHeaders) { // 有些头(如Host)WebRequest会自动处理,这里跳过避免报错 if (!WebHeaderCollection.IsRestricted(header.Key)) { request.Headers.Add(header.Key, header.Value); } } // 写入multipart内容到请求流 using (var requestStream = request.GetRequestStream()) { var encoding = Encoding.UTF8; foreach (var part in parts) { // 写入当前部分的边界和头信息 var partHeaderBuilder = new StringBuilder(); partHeaderBuilder.AppendLine($"--{boundary}"); partHeaderBuilder.AppendLine($"Content-Type: {part.ContentType}"); // 如果是二进制内容,显式指定Content-Length更严谨 if (part.BinaryContent != null) { partHeaderBuilder.AppendLine($"Content-Length: {part.BinaryContent.Length}"); } // 头和内容之间的空行 partHeaderBuilder.AppendLine(); var headerBytes = encoding.GetBytes(partHeaderBuilder.ToString()); requestStream.Write(headerBytes, 0, headerBytes.Length); // 写入部分内容 if (part.TextContent != null) { var contentBytes = encoding.GetBytes(part.TextContent); requestStream.Write(contentBytes, 0, contentBytes.Length); } else if (part.BinaryContent != null) { requestStream.Write(part.BinaryContent, 0, part.BinaryContent.Length); } // 写入部分结束的换行 requestStream.Write(encoding.GetBytes("\r\n"), 0, 2); } // 写入结束边界 var endBoundaryBytes = encoding.GetBytes($"--{boundary}--\r\n"); requestStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length); } return request.GetResponse(); } } // 辅助类:存储单个multipart部分的信息 public class MultipartPart { // 当前部分的Content-Type public string ContentType { get; set; } // 文本类型的内容(比如JSON) public string TextContent { get; set; } // 二进制类型的内容(比如文件、字节数组) public byte[] BinaryContent { get; set; } }
调用示例
按照你给出的请求格式,这样调用就能生成符合要求的请求:
// 1. 准备自定义请求头 var customHeaders = new Dictionary<string, string> { { "Accept", "application/json" }, { "Vendor", "vendor1" }, { "Product", "Test" }, { "Product-Version", "1.0.0" }, { "Plugin-Version", "0.0.1" } }; // 2. 准备multipart的各个部分 var parts = new List<MultipartPart> { // 示例:添加一个JSON部分 new MultipartPart { ContentType = "application/json", TextContent = "{\"data\":\"sample-content\"}" }, // 如果需要二进制部分,比如文件,可添加: // new MultipartPart // { // ContentType = "application/octet-stream", // BinaryContent = File.ReadAllBytes(@"C:\test-file.bin") // } }; // 3. 发送请求 var helper = new MultipartRequestHelper(); var response = helper.SendMultipartRequest("http://google.com:9010/api/lalala", parts, customHeaders); // 4. 处理响应(示例) using (var responseStream = response.GetResponseStream()) using (var reader = new StreamReader(responseStream)) { var responseContent = reader.ReadToEnd(); Console.WriteLine(responseContent); }
关键注意事项
- 边界字符串:一定要选一个不会出现在任何请求内容里的字符串,避免解析错误。如果担心冲突,可以生成随机字符串(比如
Guid.NewGuid().ToString("N"))。 - 换行格式:HTTP标准要求用
\r\n作为换行,不能只用\n,否则服务器可能解析失败。 - Content-Length:虽然
HttpWebRequest可以自动计算内容长度,但手动处理二进制内容的Content-Length会更严谨。 - 受限头:有些HTTP头(比如
Host、Content-Length)是WebRequest自动管理的,不要手动添加,否则会抛出异常。
内容的提问来源于stack exchange,提问作者tmt
相关产品推荐
相关产品推荐

