我正在使用Nreco PDF将html页面转换为PDF。最近实现了捆绑和最小化,因此在web配置中设置了compilation debug = false
。
从那时起,PDF生成失败,chrome显示这条消息,上面写着"加载PDF文档失败"。
当我打开调试模式时,一切都按预期进行。
以下是代码片段:
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();
}
我想知道当使用debug=false运行时,是什么导致此代码失败。
不需要回答:
用try装饰代码->catch,调试并查看catch中是否有任何错误,很可能是htmlToPdf。GeneratePdf将失败,如果不继续下一个调试步骤
在将字节存储PDF返回到解决方案中的App_Data文件夹之前,请确保您的PDF生成器工作正常,这意味着您将拥有一个有效的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用于压缩内容或最小化控制器操作结果被压缩不正确(是正确的,但不符合您返回pdf的方式)。
webMarkupMin默认设置如下:
enableMinification="真";
disableMinificationInDebugMode=";false";
enableCompression=";真";
disableCompressionInDebugMode=";false";
这就是在调试模式下正确运行的原因
编译调试="真";
调试时得到相同的错误=";真";在web.config集中:
<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 File(pdfBytes, "application/pdf");
不要使用响应。BinaryWrite()直接返回字节,这将导致迷你程序无法读取pdf流,因此向客户端返回空响应