ASP.NET Core中Request.Body和Request.Content的区别及文件流获取方法
ASP.NET Core Web API 从Request.Body获取上传文件流实现方案
前置说明
你之前用StreamReader.ReadToEndAsync读的是文本类型请求体,文件上传是二进制流,不需要转文本,直接操作流即可。根据你用Postman测试的场景,分两种实现方式:
场景1:Postman用Binary模式上传原始文件流
这种模式请求体就是纯文件二进制内容,无需额外解析,适合单文件纯上传、无其他表单参数的场景:
- 控制器代码示例
[HttpPost("upload/raw")] [DisableRequestSizeLimit] // 按需取消上传大小限制,也可以用RequestSizeLimit指定具体值 public async Task<IActionResult> UploadRawFile() { // 大文件上传建议开启按需缓冲,超过阈值自动存磁盘,避免占满内存 Request.EnableBuffering(bufferThreshold: 1024 * 1024 * 10, bufferLimit: null); // 自定义文件保存路径 var savePath = Path.Combine("你的本地存储目录", Guid.NewGuid().ToString("N") + Path.GetExtension("你要保存的文件名")); using var writeStream = new FileStream(savePath, FileMode.Create, FileAccess.Write); // 直接把Request.Body拷贝到文件流即可 await Request.Body.CopyToAsync(writeStream).ConfigureAwait(false); return Ok(new { SavePath = savePath, FileSize = writeStream.Length }); }
- Postman配置
- 请求方式选POST,填好接口地址
- 切换到Body标签页,选中
binary选项,点击「Select File」选择要上传的文件,直接发送请求即可。
场景2:Postman用form-data模式上传(携带其他表单参数)
这种模式请求是multipart/form-data格式,Request.Body包含分隔符、表单字段、文件内容等复合信息,需要用MultipartReader解析:
- 控制器代码示例
[HttpPost("upload/form")] [DisableRequestSizeLimit] public async Task<IActionResult> UploadFormFile() { // 校验请求格式 if (!Request.ContentType.StartsWith("multipart/form-data", StringComparison.OrdinalIgnoreCase)) { return BadRequest("仅支持multipart/form-data格式的上传请求"); } // 提取multipart分隔符 var mediaTypeHeader = Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse(Request.ContentType); var reader = new MultipartReader(mediaTypeHeader.Boundary.Value, Request.Body); MultipartSection section; // 遍历所有表单段 while ((section = await reader.ReadNextSectionAsync()) != null) { var contentDisposition = Microsoft.Net.Http.Headers.ContentDispositionHeaderValue.Parse(section.ContentDisposition); // 识别文件段 if (contentDisposition.DispositionType.Equals("form-data") && !string.IsNullOrEmpty(contentDisposition.FileName.Value)) { var fileName = contentDisposition.FileName.Value; var savePath = Path.Combine("你的本地存储目录", fileName); using var writeStream = new FileStream(savePath, FileMode.Create, FileAccess.Write); await section.Body.CopyToAsync(writeStream).ConfigureAwait(false); // 单文件上传读完直接返回,多文件可以继续遍历 return Ok(new { FileName = fileName, SavePath = savePath, FileSize = writeStream.Length }); } // 读取其他表单参数(可选) else if (contentDisposition.DispositionType.Equals("form-data") && !string.IsNullOrEmpty(contentDisposition.Name.Value)) { using var streamReader = new StreamReader(section.Body); var fieldName = contentDisposition.Name.Value; var fieldValue = await streamReader.ReadToEndAsync(); // 自定义处理表单参数逻辑 } } return BadRequest("未检测到上传的文件"); }
- Postman配置
- 切换到Body标签页,选中
form-data选项 - Key列输入文件字段名,鼠标悬停在Key输入框右侧,下拉选择类型为
File - Value列点击「Select Files」选择要上传的文件,需要加其他表单参数的话新增行,类型选
Text填对应键值即可。
常见问题处理
如果遇到Request.Body读取为空的情况,可做如下配置:
- 在Action上添加
[IgnoreAntiforgeryToken]特性,避免防伪校验提前读取请求体 - 在Program.cs中配置表单参数限制:
builder.Services.Configure<Microsoft.AspNetCore.Http.Features.FormOptions>(options => { options.MultipartBodyLengthLimit = long.MaxValue; // 按需调整最大上传大小 options.BufferBody = false; });
内容的提问来源于stack exchange,提问作者Anil Anjana
相关产品推荐
相关产品推荐

