当应用程序 运行 且编译调试 = false 时,PDF 生成失败

PDF Generation fails when the application is run with compilation debug = false

我正在使用 Nreco PDF 将 html 页转换为 PDF。最近实施了捆绑和缩小,因此在网络配置中设置了 compilation debug = false

此后 PDF 生成失败,chrome 显示此消息 "Failed to Load PDF Document"。

当我打开调试模式时,一切正常。

这是代码片段:

public ActionResult ABC()
{
    var htmlContent =System.IO.File.ReadAllText(Server.MapPath("~/Views/abc/abc.html"));
    createpdf(htmlContent);
}

public void createpdf(string htmlContent)
{
    var htmlToPdf = new NReco.PdfGenerator.HtmlToPdfConverter();
    var pdfBytes = htmlToPdf.GeneratePdf(htmlContent);

    Response.ContentType = "application/pdf";
    Response.ContentEncoding = System.Text.Encoding.UTF8;
    Response.AddHeader("Content-Disposition", "Inline; filename=TEST.pdf");
    Response.BinaryWrite(pdfBytes);
    Response.Flush();
    Response.End();
}

我想知道当 运行 调试 =false 时导致此代码失败的原因。

不需要回答:

用 try -> catch 修饰代码,调试并查看 catch 中是否有任何错误,很可能 htmlToPdf.GeneratePdf 会失败,如果不继续下一步的调试步骤

确保您的 PDF 生成器工作正常,这意味着您将拥有一个有效的 pdf 文件,然后return将字节存储在您的 App_Data 解决方案中的 pdf 文件夹中

   var appDataPath = Server.MapPath("~/App_Data");
   var filename = string.Format(@"{0}.pdf", DateTime.Now.Ticks);
   var path = Path.Combine(appDataPath, filename);
   System.IO.File.WriteAllBytes(path, pdfBytes.ToArray());

检查创建和关闭响应

Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.ContentEncoding = System.Text.Encoding.UTF8;
Response.AddHeader("Content-Disposition", "Inline; filename=TEST.pdf");
Response.BinaryWrite(pdfBytes);
Response.Flush();
Response.Close()
Response.End()

编辑: 经过长时间的调试会话,发现了什么: 当使用 WebMarkupMin.Mvc 压缩内容或最小化 Controller Action 结果压缩不正确(是正确的,但不符合您 return pdf 的方式)。

webMarkupMin 默认设置如下:

enableMinification="true"

disableMinificationInDebugMode="false"

enableCompression="true"

disableCompressionInDebugMode="false"

这就是为什么在调试模式下运行在

时正确的原因

compilation debug="true"

当 web.config 中的 debug="true" 设置时出现相同的错误:

<webMarkupMin xmlns="http://tempuri.org/WebMarkupMin.Configuration.xsd">
  <webExtensions enableMinification="true" disableMinificationInDebugMode="false" enableCompression="true" disableCompressionInDebugMode="false" />
 <!-- rest of shebang -->
</webMarkupMin>

您可能会问的问题在哪里,在您的实现中很简单响应流压缩不正确。

克服问题:

 //you can use FileResult, same outcome
    public ActionResult ABC()
            {
                var htmlContent = System.IO.File.ReadAllText(Server.MapPath("~/Views/abc/abc.html"));
                var htmlToPdf = new NReco.PdfGenerator.HtmlToPdfConverter();
                var pdfBytes = htmlToPdf.GeneratePdf(htmlContent);
                //return File(pdfBytes, "application/pdf", "TEST.pdf"); 
                //will add filename to your response, downside is that browser downloads the response

                //if your really need Content Disposition in response headers uncomment below line
                //Response.AddHeader("Content-Disposition", "Inline; filename=TEST.pdf");
                return File(pdfBytes, "application/pdf");
                
            }

更改为使用 File() 来 return 字节,例如: return File(pdfBytes, "application/pdf"); 不要直接使用 Response.BinaryWrite() return 字节,这会导致 minifer 无法读取 pdf 流,因此 return 对客户端的空响应