基于ASP.NET Core与Angular实现文件下载功能的问题排查
问题分析与解决方案
看起来你遇到的核心问题是:服务端明明生成了正常大小的PDF文件(49648字节),但前端下载的文件却只有1KB,这是因为代码里有两个关键错误导致的,我来逐一帮你修正:
错误点1:Angular端未正确获取响应体数据
你当前在调用downloadFile时传入的是整个HttpResponse对象,而不是响应里的实际Blob内容。当responseType设为'blob'时,HttpResponse的body属性才是我们需要的文件Blob数据。
修改后的Angular代码:
uploadAndProgress(files: File[]){ console.log(files) var formData = new FormData(); Array.from(files).forEach(f => formData.append('file',f)) this.http.post('http://localhost:5000/api/DocumentToPdf/Document', formData, { reportProgress: true, responseType: 'blob', observe: 'events' }).subscribe(event => { if (event.type === HttpEventType.UploadProgress) { this.percentDone = Math.round(100 * event.loaded / event.total); } else if (event instanceof HttpResponse) { this.uploadSuccess = true; console.log('Success'); // 传入response的body属性,而不是整个event对象 this.downloadFile(event.body, 'download.pdf'); } }); } // 方法参数改为Blob类型,直接使用saveAs即可 downloadFile(data: Blob, filename: string) { saveAs(data, filename); }
错误点2:ASP.NET Core控制器返回类型不符合框架规范
在ASP.NET Core中,直接返回HttpResponseMessage并不是推荐的做法,框架会将其当作普通对象序列化,而不是正确处理文件流的响应,这会导致返回的内容不是实际的PDF字节,而是序列化后的对象元数据(这就是为什么下载文件只有1KB的原因)。我们应该改用框架原生的File方法返回文件内容,同时还要注意重置内存流的位置到开头,否则读取不到完整内容。
修改后的ASP.NET Core控制器代码:
[Route("api/[controller]")] [ApiController] public class DocumentToPdfController : ControllerBase { private readonly IDocumentToPdf _documentToPdf; public DocumentToPdfController(IDocumentToPdf documentToPdf) { _documentToPdf = documentToPdf; } [HttpPost("Document")] public IActionResult Document() { try { var files = Request.Form.Files; if (files.Count == 0) { return BadRequest("No file was uploaded."); } using var fileStream = files[0].OpenReadStream(); var pdfStream = _documentToPdf.DocumentToPdf(fileStream); // 重置流的位置到开头,否则读取时会从流的末尾开始,返回空内容 pdfStream.Position = 0; // 使用File方法返回PDF文件,指定正确的MIME类型 return File(pdfStream, "application/pdf", "pdf.pdf"); } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine(ex.StackTrace); return StatusCode(StatusCodes.Status500InternalServerError, "Failed to process document"); } } }
完成这两处修改后,前端应该就能正确下载到完整大小的PDF文件了。
内容的提问来源于stack exchange,提问作者classname13
相关产品推荐
相关产品推荐

