3

I have an MVC3 application that needs to generate large reports on a regular basis. The user can choose their criteria and launch the report. Right now I am opening a new tab/window with the javascript window.open() method. While the report is getting generated the user can not use the site. Everything waits till the report is generated. The code for generating the report is:

private FileStreamResult doSpecReport(List<int> idProjItems)
{
    PdfDocument outputDocument = new PdfDocument(); // returning to the user
    foreach(var id in idProjItems)
    {
        var item = _entities.ProjectEquipmentItems.First(f => f.idProjectEquipmentItem == id);
        var cutsheetPath = item.CutSheet;
        Dictionary<string, string> dictionary = new Dictionary<string, string>();
        dictionary.Add("p_idEquipmentItem", id.ToString());
        var fs = GetReportHtml("NameOfReport", dictionary); // Returns FileStreamResult from crystal

        var inputDocument1 = CompatiblePdfReader.Open(fs.FileStream); // add report to output doc
        int count = inputDocument1.PageCount;
        for(int idx = 0; idx < count; idx++) 
        {
            PdfPage page = inputDocument1.Pages[idx];
            outputDocument.AddPage(page);
        }

        if (!string.IsNullOrEmpty(cutsheetPath))
        {
            cutsheetPath = Path.Combine(Server.MapPath("~/Files/CutSheetFiles/"), cutsheetPath);
            if (File.Exists(cutsheetPath))
            {
                var inputDocument2 = CompatiblePdfReader.Open(cutsheetPath);//, PdfDocumentOpenMode.Import);
                count = inputDocument2.PageCount;
                for(int idx = 0; idx < count; idx++)
                {
                    PdfPage page = inputDocument2.Pages[idx];
                    outputDocument.AddPage(page);
                }
            }
        }
    }

    var ms = new MemoryStream();
    outputDocument.Save(ms, false);
    ms.Position = 0;

    return new FileStreamResult(ms, "application/pdf")
    {
        FileDownloadName = "Report.pdf"
    };
}

I am not sure if I am doing anything wrong, I don't understand why this process takes up all the browser's resources. Thanks for any help.

Update: One version of the code that calls doSpecReport. The code around the success doesn't work.

$.ajax({
    url: url,
    data: qdata,
    type: "POST",
    success: function (result) { // this doesn't actually work.
        var obj = $('<object type="application/pdf" width="100%" height="100%" border="2"></object>');
        obj.attr('data', 'data:application/pdf;base64,' + result);
        $(".mask").hide();
        $('#divContainer').append(obj);
    }
});
abatishchev
  • 98,240
  • 88
  • 296
  • 433
smash51
  • 31
  • 3
  • this looks like C# code, not JavaScript; the browser on the end user's system wouldn't be doing anything but waiting for the return from the server... you would need to use some sort of async call if you want the browser to stay responsive while the server does it's processing.... – Claies Oct 03 '13 at 19:54
  • You are correct, the javascript tag is due to how I open the window that calls this code. I was thinking that there may be some way to modify that code, to ensure this code runs in a different thread. And sending the request via ajax still holds the site hostage. – smash51 Oct 03 '13 at 20:52
  • can you post the actual JavaScript code that you are trying to use to make the call asynchronous? – Claies Oct 03 '13 at 20:59
  • Edited my question to add the code. – smash51 Oct 03 '13 at 21:08

1 Answers1

0

You have to generate a temporary file location on the server side and return the location url. You cannot set HTML Document contents with binary PDF. Can you generate the report and store it in a temp location and pass its url link in the response. Assuming that doSpecReport generates a temp pdf file named mypdf.pdf,

Then in your success block, you can add it to the object data attribute so that the end object looks like this

  <object width="400" height="500" type="application/pdf" data="/my_pdf.pdf?#zoom=85&scrollbar=0&toolbar=0&navpanes=0" id="pdf_content">

  </object>
Community
  • 1
  • 1
Pradeep Mahdevu
  • 7,613
  • 2
  • 31
  • 29
  • My real problem is that even when I do this, and I have already this, the site doesn't respond until the whole process is finished. I want to spawn a report in another window, then be able to use the website while that is working. I don't want to write the file to disk. We are going to implement a new site in IIS that points to a report server style project. – smash51 Oct 04 '13 at 16:01
  • Just to clarify - When you say your site does not respond. I am assuming, you are getting locked on the JavaScript side not on the server side. Right? Are you even hitting the success block ever on the client side? If you want to spawn a report in another window - why are you doing a $.ajaxPost? Why not use window.open() with a random url which server understands how to serve. – Pradeep Mahdevu Oct 04 '13 at 16:50
  • I do a window.open to the url that does the work and returns the pdf. While this window is running and has not returned my pdf, my site is locked up, meaning if I want to move to a different page, I can't. If I do a window.open to a page that kicks off an ajaxPost, the same problem occurs. – smash51 Oct 04 '13 at 17:30
  • Are you using ASP .net dev server? This server [cannot process more than one request at a time.](http://stackoverflow.com/questions/3261144/asp-net-dev-server-cassini-iis-express-and-multiple-threads) . I guess that is the reason, you are not able to do anything. – Pradeep Mahdevu Oct 04 '13 at 18:01
  • The behavior is seen on a windows server 2008 box with IIS7 as well as my dev laptop which is running IIS Express for this project. – smash51 Oct 04 '13 at 18:13
  • 1
    OK @smash51, thanks for being patient. Its getting interesting. :) Can you please do a couple of things. I think your IIS Express is not processing multiple requests. Are you using [ASP.NET session states](http://stackoverflow.com/questions/9672566/iis-express-7-5-not-processing-requests-concurrently). I have a feeling its the server. Is there any other way you can confirm if server is processing multiple requests in parallel. – Pradeep Mahdevu Oct 04 '13 at 18:24
  • I am not using session states, and IIS Express is only on my laptop. I am still seeing this behavior on the server that is running IIS7. – smash51 Oct 04 '13 at 19:17