.NET Blazor WebAssembly调用POST API下载PDF遇反序列化错误
解决Blazor WebAssembly中POST下载PDF的反序列化错误问题
问题原因
你当前的代码错误在于使用了HttpPost<string>方法,该方法默认会将API返回的响应内容当作JSON字符串进行反序列化,但后端返回的是二进制PDF文件(开头通常是%PDF-),这显然不是合法的JSON格式,因此触发了反序列化异常。
解决方案
需要直接获取API返回的二进制字节流,而非尝试反序列化为JSON,然后通过浏览器的下载机制触发PDF文件的保存。具体步骤如下:
1. 修改前端HTTP调用逻辑
替换原来的HttpPost<string>,改为直接使用HttpClient.PostAsync获取响应的二进制内容:
private async Task generateServiceAgreement() { // 准备请求内容(将模型序列化为JSON) var jsonContent = JsonContent.Create(this.ServicePlanModel); // 发送POST请求,确保接受PDF类型响应 var response = await httpService.HttpClient.PostAsync("service-plan", jsonContent); response.EnsureSuccessStatusCode(); // 校验请求是否成功 // 读取二进制PDF内容 var pdfBytes = await response.Content.ReadAsByteArrayAsync(); // 触发浏览器下载 await DownloadFile("agreement.pdf", pdfBytes, "application/pdf"); }
2. 实现浏览器下载功能
Blazor WebAssembly无法直接操作浏览器下载对话框,需要通过JS互操作实现:
首先在组件的@code块中注入IJSRuntime:
[Inject] private IJSRuntime JSRuntime { get; set; }
然后添加下载方法:
private async Task DownloadFile(string fileName, byte[] fileBytes, string contentType) { using var stream = new MemoryStream(fileBytes); await JSRuntime.InvokeVoidAsync( "downloadFile", fileName, contentType, await stream.ToArrayAsync() ); }
最后在wwwroot/index.html中添加对应的JavaScript函数:
<script> window.downloadFile = (fileName, contentType, byteArray) => { const blob = new Blob([byteArray], { type: contentType }); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = fileName; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(url); }; </script>
额外说明
- 后端代码无需修改,
Results.File(pdf, "application/pdf", "agreement.pdf")的返回逻辑是正确的,已指定了正确的内容类型和文件名。 - 如果你的
httpService封装了HttpClient并强制设置了Accept: application/json,需要在请求时覆盖为application/pdf:jsonContent.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/pdf"));
内容的提问来源于stack exchange,提问作者hanushi-thana
相关产品推荐
相关产品推荐

