You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Framework 4.0下不依赖BCL实现multipart/mixed HTTP请求

在.NET Framework 4.0中用HttpWebRequest实现multipart/mixed请求

完全没问题!既然你已经能用HttpWebRequest发送简单请求,只需要扩展它来处理multipart/mixed的格式规则就行——核心就是用边界字符串分隔各个请求部分,并且严格遵循HTTP的格式要求。下面是具体的实现方案:

核心思路

multipart/mixed请求的关键是边界(boundary):

  1. 在Content-Type头中指定边界字符串(比如你示例里的batch-1)
  2. 每个请求部分以--{boundary}开头,后跟该部分的HTTP头(比如Content-Type)
  3. 部分头和内容之间必须留一个空行(\r\n)
  4. 所有部分结束后,用--{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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:23:51