ASP.NET 5 如何实现流式接收上传文件并直接存储到MongoDB GridFS
实现步骤
1. 服务注册
首先将你实现的MongoDB上传服务注册到ASP.NET依赖注入容器中,在Startup.cs的ConfigureServices方法中添加如下代码:
// 替换为你实际的服务接口与实现类名 services.AddScoped<IMongoUploadService, MongoUploadService>();
2. 控制器实现
直接在你已创建的UploadsController中实现如下逻辑即可,全程无需缓冲完整文件:
[ApiController] [Route("api/[controller]")] public class UploadsController : ControllerBase { // 替换为你实际的上传服务类型 private readonly IMongoUploadService _uploadService; public UploadsController(IMongoUploadService uploadService) { _uploadService = uploadService; } [HttpPost] // 如需限制上传大小,替换为 [RequestSizeLimit(你允许的最大字节数)] [DisableRequestSizeLimit] public async Task<IActionResult> Upload() { // 校验请求类型合法性 if (!Request.ContentType.StartsWith("multipart/form-data", StringComparison.OrdinalIgnoreCase)) { return BadRequest("仅支持multipart/form-data类型请求"); } // 解析请求boundary var boundary = Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse(Request.ContentType).Boundary.Value; if (string.IsNullOrWhiteSpace(boundary)) { return BadRequest("请求未包含合法的boundary参数"); } // 绑定请求原始流创建MultipartReader,无额外缓冲 var reader = new Microsoft.AspNetCore.WebUtilities.MultipartReader(boundary, Request.Body); Microsoft.AspNetCore.WebUtilities.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 = System.Net.WebUtility.HtmlDecode(contentDisposition.FileName.Value); // 直接将分段流传入MongoDB上传服务,边接收边写入GridFS var fileId = await _uploadService.UploadFromStreamAsync(section.Body, fileName); return Ok(new { FileId = fileId, FileName = fileName }); // 如需支持多文件上传,删除return语句继续遍历下一个分段即可 } } return BadRequest("请求中未检测到上传文件"); } }
核心注意事项
- 不要给Action添加任何
[FromForm]参数,也不要主动调用Request.Form相关属性,否则会触发ASP.NET默认的表单解析逻辑,将整个请求缓冲到内存或磁盘临时文件,违背流式处理的需求 MultipartReader读取的是请求原始的HTTP流,UploadFromStreamAsync内部会直接从这个流读取数据写入GridFS,数据从客户端到API再到MongoDB全程流式流转,不会存储完整文件副本- 如需限制上传大小,将
[DisableRequestSizeLimit]替换为[RequestSizeLimit(最大允许字节数)]即可
内容的提问来源于stack exchange,提问作者tvandinther
相关产品推荐
相关产品推荐

