ASP.NET:如何从HttpContext.Request参数中获取文件字节数组
从MultipartFormData请求中获取准确文件字节数组的方法
背景场景
客户端通过HttpClient的MultipartFormDataContent向ASHX服务端上传文件及参数,客户端代码如下:
HttpClient client = new HttpClient(); MultipartFormDataContent multipartContent = new MultipartFormDataContent(); if (!string.IsNullOrEmpty(attachFileName) && attachContent != null && attachContent.Length > 0) { var imageBinaryContent = new ByteArrayContent(attachContent); multipartContent.Add(imageBinaryContent, attachFileName); multipartContent.Add(new StringContent(attachFileName), "attachFileName"); } multipartContent.Add(new StringContent("xxx"), "subject"); var response = client.PostAsync(url, multipartContent).Result;
服务端原代码直接读取整个请求输入流,导致获取的文件损坏:
MemoryStream ms = new MemoryStream(); context.Request.InputStream.CopyTo(ms); byte[] data = ms.ToArray();
问题原因
直接读取整个输入流得到的是完整的Multipart请求数据,其中包含了请求分隔符、参数头、文件头等额外内容,并非纯文件字节数组,因此文件会损坏。
正确解决方案
使用ASP.NET内置的HttpFileCollection解析Multipart请求中的文件:
// 获取所有上传的文件 HttpFileCollection uploadedFiles = context.Request.Files; if (uploadedFiles.Count > 0) { // 取第一个上传的文件(对应客户端上传的文件) HttpPostedFile targetFile = uploadedFiles[0]; byte[] fileBytes = new byte[targetFile.ContentLength]; // 读取文件流到字节数组 targetFile.InputStream.Read(fileBytes, 0, targetFile.ContentLength); // fileBytes即为准确的文件字节数组,可直接使用 }
额外优化建议
- 客户端上传文件时,建议显式设置文件的Content-Disposition和Content-Type,避免服务端解析歧义:
var imageBinaryContent = new ByteArrayContent(attachContent); // 设置文件的表单字段名和文件名 imageBinaryContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "\"file\"", FileName = $"\"{attachFileName}\"" }; // 根据文件类型设置Content-Type,比如图片用image/jpeg,通用文件用application/octet-stream imageBinaryContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream"); multipartContent.Add(imageBinaryContent); - 服务端获取其他参数可直接通过
context.Request.Form:// 获取文件名参数 string fileName = context.Request.Form["attachFileName"]; // 获取subject参数 string subject = context.Request.Form["subject"];
内容的提问来源于stack exchange,提问作者Robin Sun
相关产品推荐
相关产品推荐

