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

C#中如何在MultipartHttpRequest中随文件传递Dictionary<string,string>

问题解决:Multipart请求中Dictionary类型参数传递为null的问题

问题分析

你的代码已尝试将Filters序列化为JSON后作为form-data字段传递,但后端接收始终为null,大概率是以下原因导致:

  • 字段名大小写不匹配(比如后端期望filters,但你传递的是Filters)
  • 未指定JSON格式的Content-Type,后端无法识别数据类型
  • 边界写入的顺序或格式错误,导致解析异常

修正方案

针对上述问题,修改代码如下:

关键修改点

  1. 统一字段名与后端接收参数的大小写
  2. 为Filters字段添加Content-Type: application/json头,明确数据格式
  3. 调整边界写入逻辑,避免多余换行导致的解析问题
  4. 重置文件流位置,确保完整读取文件内容

修改后的完整代码

private async Task<string> SendMultiPartHttpRequest(string url, Dictionary<string,string> headers, NameValueCollection values, Dictionary<string,MemoryStream> files)
{
    string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
    // 基础边界(去掉开头的\r\n,第一个字段前无需额外换行)
    byte[] boundaryBytes = Encoding.UTF8.GetBytes("--" + boundary + "\r\n");
    // 结尾边界
    byte[] trailer = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Timeout = 100000;
    request.ReadWriteTimeout = 100000;
    request.ContentType = "multipart/form-data; boundary=" + boundary;
    request.Method = "POST";
    request.Headers.Add("Accept", "*/*");
    request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
    request.Headers.Add("Connection", "keep-alive");

    using (Stream requestStream = await request.GetRequestStreamAsync())
    {
        if (headers != null && headers.Any())
        {
            foreach (var key in headers.Keys)
            {
                request.Headers.Add(key, headers[key]);
            }
        }

        bool hasWrittenContent = false;

        // 处理普通表单参数
        if (values != null)
        {
            foreach (string key in values.Keys)
            {
                if (hasWrittenContent)
                {
                    await requestStream.WriteAsync(Encoding.UTF8.GetBytes("\r\n"), 0, 2);
                }
                await requestStream.WriteAsync(boundaryBytes, 0, boundaryBytes.Length);
                byte[] formItemBytes = Encoding.UTF8.GetBytes(string.Format("Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}", key, values[key]));
                await requestStream.WriteAsync(formItemBytes, 0, formItemBytes.Length);
                hasWrittenContent = true;
            }
        }

        // 处理Filters字典
        Dictionary<string, string> filters = new Dictionary<string, string>
        {
            { "IsConfidential", "true" },
            { "IsArchived", "false" }
        };

        if (filters != null && filters.Any())
        {
            if (hasWrittenContent)
            {
                await requestStream.WriteAsync(Encoding.UTF8.GetBytes("\r\n"), 0, 2);
            }
            await requestStream.WriteAsync(boundaryBytes, 0, boundaryBytes.Length);
            string filtersJson = JsonConvert.SerializeObject(filters);
            // 添加JSON类型的Content-Type头
            byte[] filtersBytes = Encoding.UTF8.GetBytes(
                $"Content-Disposition: form-data; name=\"Filters\"\r\nContent-Type: application/json\r\n\r\n{filtersJson}");
            await requestStream.WriteAsync(filtersBytes, 0, filtersBytes.Length);
            hasWrittenContent = true;
        }
        
        // 处理文件上传
        if (files != null && files.Any())
        {
            foreach (string key in files.Keys)
            {
                if (hasWrittenContent)
                {
                    await requestStream.WriteAsync(Encoding.UTF8.GetBytes("\r\n"), 0, 2);
                }
                await requestStream.WriteAsync(boundaryBytes, 0, boundaryBytes.Length);
                byte[] formItemBytes = Encoding.UTF8.GetBytes(string.Format("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: application/octet-stream\r\n\r\n", "DataFile", key));
                await requestStream.WriteAsync(formItemBytes, 0, formItemBytes.Length);

                MemoryStream memoryStream = files[key];
                memoryStream.Position = 0; // 重置流位置,确保从开头读取
                int bytesRead = 0;
                byte[] buffer = new byte[2048];
                while ((bytesRead = memoryStream.Read(buffer, 0, buffer.Length)) != 0)
                {
                    await requestStream.WriteAsync(buffer, 0, bytesRead);
                }
                hasWrittenContent = true;
            }
        }

        // 写入结尾边界
        await requestStream.WriteAsync(trailer, 0, trailer.Length);
    }

    using (StreamReader reader = new StreamReader((await request.GetResponseAsync()).GetResponseStream()))
    {
        return await reader.ReadToEndAsync();
    };
}

内容的提问来源于stack exchange,提问作者Sanjeev Gautam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 23:13:19