在C#中通过API下载SQL存储的Word Docx文件时解析失败的解决方法
解决“Http failure during parsing”错误:从SQL varbinary下载Word文档
问题根源分析
- 空字节数组导致解析异常:当未找到文档时,你返回了空的
byte[],后端会生成一个空文件流返回给前端。如果前端默认将响应按JSON解析,空内容会直接触发解析失败。 - MemoryStream位置未重置:用字节数组初始化
MemoryStream后,流的读取指针处于数组末尾,前端无法读取到有效内容,也会间接引发解析错误。
修复后的后端代码
1. 修正文档查询方法,明确处理无文档场景
public async Task<byte[]> GetUserAnswerFileAsync(int studentId, int testId) { var docs = await GetUserAnswerDocumentAsync(studentId, testId); var doc = docs?.FirstOrDefault(); if (doc?.TestDocument is null) { // 抛出明确异常,让上层处理404逻辑 throw new FileNotFoundException("未找到对应的学生答卷文档"); } return doc.TestDocument; }
2. 修正下载接口,重置流位置并处理异常
public async Task<IActionResult> DownloadFileFromDataBase(int testId, int studentId) { try { var answerSheetBytes = await _testRepository.GetUserAnswerFileAsync(studentId, testId); MemoryStream ms = new MemoryStream(answerSheetBytes); // 重置流指针到起始位置,确保前端能读取完整内容 ms.Position = 0; return new FileStreamResult(ms, "application/vnd.openxmlformats-officedocument.wordprocessingml.document") { FileDownloadName = $"学生{studentId}_{testId}号测试答卷.docx" // 设置明确的下载文件名 }; } catch (FileNotFoundException ex) { return NotFound(ex.Message); } }
前端配合处理(关键)
确保前端请求时明确指定响应类型为二进制blob,避免把文件流当成JSON解析。以Angular为例:
this.http.get('/api/your-download-endpoint', { params: { testId: '1', studentId: '123' }, responseType: 'blob' }).subscribe(blob => { // 触发浏览器下载 const url = window.URL.createObjectURL(blob); const downloadLink = document.createElement('a'); downloadLink.href = url; downloadLink.download = '学生答卷.docx'; document.body.appendChild(downloadLink); downloadLink.click(); window.URL.revokeObjectURL(url); document.body.removeChild(downloadLink); });
内容的提问来源于stack exchange,提问作者Zidane
相关产品推荐
相关产品推荐

