You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET MVC返回带PDF的JSON后文件损坏无法打开求助

解决ASP.NET MVC返回JSON包含PDF数据导致文件损坏的问题

问题根源

JSON协议本身不支持直接传输二进制数据,ASP.NET MVC默认会将byte[]类型序列化为Base64编码的字符串。但你的前端代码直接将这个Base64字符串当作原始二进制数据传入Blob,相当于把字符串的UTF-8编码字节写入了PDF文件,这就导致了PDF文件格式损坏无法正常打开。

修复方案

1. 服务端修改:将PDF字节数组转为Base64字符串

首先修改CombinedData类的PdfData字段类型为string,并在生成数据时将字节数组转换为Base64编码:

// 定义CombinedData类
public class CombinedData
{
    public string Text { get; set; }
    public string PdfData { get; set; } // 改为string类型存储Base64编码
    public string FileName { get; set; }
}

// 修改BuildPDF Action
public ActionResult BuildPDF() 
{
    // <原有生成PDF的代码保持不变>
    PdfFileEditor oEditor = new PdfFileEditor();
    oEditor.Concatenate(printdocs.ToArray(), printfinalStream);
    printfinalStream.Seek(0, SeekOrigin.Begin);

    var combinedData = new CombinedData
    {
        Text = msg,
        PdfData = Convert.ToBase64String(printfinalStream.ToArray()), // 转成Base64字符串
        FileName = "Authorization_" + GetNewGuid() + ".pdf"
    };

    return Json(combinedData, JsonRequestBehavior.AllowGet);
}

2. 前端修改:将Base64字符串解码为二进制字节数组

在AJAX的success回调中,先把Base64字符串解码为原始的Uint8Array,再生成Blob进行下载:

$.ajax({
   type: 'GET',
   url: '@Url.Action("PrintandEmailAuthorization", "Forms")',
   data: {
          // 原有参数保持不变
          "LetterDated": obj.LetterDated, "AuthDated": obj.AuthDated, "ReturnBy": obj.ReturnBy, "ProtestMonth": obj.ProtestMonth,
          "TaxYear": obj.TaxYear, "FromFileNum": obj.FromFileNum, "ToFileNum": obj.ToFileNum, "Suffix": obj.Suffix, "PaperSource": obj.PaperSource,
          "LetterSignedBy": obj.LetterSignedBy, "Title": obj.Title, "ConsentAttorney": obj.ConsentAttorney, "includeexemption": obj.Includeexemption,
          "includethirdrequest": obj.Includethirdrequest, "includeconsent": obj.Includeconsent, "includeref": obj.Includeref,
          "AttorneyName": obj.AttorneyName, "AttorneyEmail": obj.AttorneyEmail, "TemplateName": obj.TemplateName, "TemplatePath": obj.TemplatePath, "Enclosures": obj.Enclosures,
          "OldContingencyFee": obj.OldContingencyFee, "NewContingencyFee": obj.NewContingencyFee, "ContactID": obj.ContactID, "OptionSelected": obj.OptionSelected,
          "IncludeMultLotsRe": obj.IncludeMultLotsRe, "VillTaxYear": obj.VillTaxYear, "isTest": false
      },
      success: function (data) {
                alert(data.Text);
                
                // 将Base64字符串解码为二进制字节数组
                const byteChars = atob(data.PdfData);
                const byteNums = new Array(byteChars.length);
                for (let i = 0; i < byteChars.length; i++) {
                    byteNums[i] = byteChars.charCodeAt(i);
                }
                const byteArray = new Uint8Array(byteNums);

                // 创建Blob并触发下载
                var blob = new Blob([byteArray], { type: 'application/pdf' });
                var url = window.URL.createObjectURL(blob);
                var a = document.createElement('a');
                a.style.display = 'none';
                a.href = url;
                a.download = data.FileName;
                document.body.appendChild(a);
                a.click();
                window.URL.revokeObjectURL(url);
                document.body.removeChild(a);
            }
        });

额外说明

  • Base64编码会让数据体积增加约33%,如果你的PDF文件很大,这种方案可能会影响传输效率。此时可以考虑拆分请求:先请求提示文本,再单独请求PDF文件(用原来的File返回方式)。
  • 确保服务端的printfinalStream在转换为字节数组前已经重置了位置(Seek(0, SeekOrigin.Begin)),这一步你已经做了,没问题。

内容的提问来源于stack exchange,提问作者Jonathan Small

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 01:30:59