0

I am using Nreco PDF to convert html pages to PDF . Recently Bundling and Minification was implemented and hence the compilation debug = false was set in the web config .

Since then the PDF Generation is failing and chrome shows up this message saying "Failed to Load PDF Document".

When i turn on debug mode , everything works as expected.

Here is the code snippet:

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();
}

I would like to know whats causing this code to fail when run with debug =false.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
REDEVI_
  • 684
  • 8
  • 18

2 Answers2

2

Not necessary an answer:

Decorate code with a try -> catch, debug an see if any errors in catch, most likely htmlToPdf.GeneratePdf will fail, if not continue with next debugging steps

Make sure your PDF generator is working correctly, meaning you will have a valid pdf file, before returning the bytes store pdf on you App_Data folder in solution

   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());

Check creating and closing response

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()

Edit: After long debugging sessions, what was discovered: When using WebMarkupMin.Mvc for compress content or minimization Controller Action result is compressed incorrect (is correct, but not with your way of return the pdf).

webMarkupMin default settings are as following:

enableMinification="true"

disableMinificationInDebugMode="false"

enableCompression="true"

disableCompressionInDebugMode="false"

This is the reason why in debug mode was running correct when

compilation debug="true"

To get same error when debug="true" in web.config set:

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

Where is the issue you might ask, well is simple in your implmentation Response stream is compressed incorrect.

Overcoming the problem:

 //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");
                
            }
Community
  • 1
  • 1
SilentTremor
  • 4,747
  • 2
  • 21
  • 34
  • The issue is when i run in debug mode , the file is generated properly and served . I did add a try catch block but no exceptions are occurring when run in debug mode = true , I have this issue occurring only when debug mode = false as i have stated in the question – REDEVI_ May 02 '17 at 07:06
  • also note i m reading from a html file and preparing a pdf out of it – REDEVI_ May 02 '17 at 07:14
  • Run with debug mode = false and check is file is saved if yes, debug in this way=> try, catch and finally, in finally set the only break point, check if fails in browser. – SilentTremor May 02 '17 at 07:15
  • unfortunately it doesn't work , can u help me in identifying which part of code may have a diff behavior when debug is off ? – REDEVI_ May 02 '17 at 07:28
  • What .net framework are you using? to try and replicate the thingy? – SilentTremor May 02 '17 at 07:31
  • MVC (4.5.1 .net version) – REDEVI_ May 02 '17 at 07:36
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/143156/discussion-between-redevi-and-silenttremor). – REDEVI_ May 02 '17 at 08:24
  • Check the updates, this is the only right way to do it :p – SilentTremor May 02 '17 at 18:41
  • Great job with investigation! I have tried `File` from start when trying to reproduce, but thought both approaches should work same way. – Andrii Litvinov May 02 '17 at 18:49
0

change to use File() to return the bytes, like : return File(pdfBytes, "application/pdf"); do not use the Response.BinaryWrite() directly return the bytes, this will cause the minifer can not read the pdf stream, so return a empty response to client

aspark
  • 340
  • 2
  • 7