C#中如何在MultipartHttpRequest中随文件传递Dictionary<string,string>
问题解决:Multipart请求中Dictionary类型参数传递为null的问题
问题分析
你的代码已尝试将Filters序列化为JSON后作为form-data字段传递,但后端接收始终为null,大概率是以下原因导致:
- 字段名大小写不匹配(比如后端期望
filters,但你传递的是Filters) - 未指定JSON格式的Content-Type,后端无法识别数据类型
- 边界写入的顺序或格式错误,导致解析异常
修正方案
针对上述问题,修改代码如下:
关键修改点
- 统一字段名与后端接收参数的大小写
- 为Filters字段添加
Content-Type: application/json头,明确数据格式 - 调整边界写入逻辑,避免多余换行导致的解析问题
- 重置文件流位置,确保完整读取文件内容
修改后的完整代码
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
相关产品推荐
相关产品推荐

