2013-10-03 3 views
3

J'ai une application MVC3 qui doit générer des rapports volumineux sur une base régulière. L'utilisateur peut choisir ses critères et lancer le rapport. En ce moment j'ouvre un nouvel onglet/fenêtre avec la méthode javascript window.open(). Pendant que le rapport est généré, l'utilisateur ne peut pas utiliser le site. Tout attend jusqu'à ce que le rapport soit généré. Le code pour générer le rapport est:Pourquoi mon processus de génération PDF verrouille-t-il d'autres processus ajax sur mon site?

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" 
    }; 
} 

Je ne sais pas si je fais quelque chose de mal, je ne comprends pas pourquoi ce processus prend toutes les ressources du navigateur. Merci pour toute aide.

Mise à jour: Une version du code qui appelle doSpecReport. Le code autour du succès ne fonctionne pas.

$.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); 
    } 
}); 
+0

cela ressemble à C# code, pas JavaScript; le navigateur sur le système de l'utilisateur final ne ferait rien d'autre que d'attendre le retour du serveur ... vous auriez besoin d'utiliser une sorte d'appel asynchrone si vous voulez que le navigateur reste réactif pendant que le serveur le traite. .. – Claies

+0

Vous avez raison, le tag javascript est dû à la façon dont j'ouvre la fenêtre qui appelle ce code. Je pensais qu'il pourrait y avoir un moyen de modifier ce code, pour s'assurer que ce code s'exécute dans un thread différent. Et l'envoi de la requête via ajax tient toujours le site en otage. – smash51

+0

pouvez-vous poster le code JavaScript réel que vous essayez d'utiliser pour rendre l'appel asynchrone? – Claies

Répondre

0

Vous devez générer un emplacement de fichier temporaire côté serveur et renvoyer l'URL de localisation. Vous ne pouvez pas définir le contenu d'un document HTML avec un PDF binaire. Pouvez-vous générer le rapport et le stocker dans un emplacement temporaire et transmettre son lien URL dans la réponse. En supposant que doSpecReport génère un fichier pdf nommé temp mypdf.pdf,

Puis dans votre bloc de succès, vous pouvez l'ajouter à l'attribut de données d'objet afin que l'objet final ressemble 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> 
+0

Mon vrai problème est que même lorsque je fais cela, et j'ai déjà cela, le site ne répond pas jusqu'à ce que tout le processus est terminé. Je veux générer un rapport dans une autre fenêtre, puis pouvoir utiliser le site web pendant que ça fonctionne. Je ne veux pas écrire le fichier sur le disque. Nous allons implémenter un nouveau site dans IIS qui pointe vers un projet de style de serveur de rapports. – smash51

+0

Juste pour clarifier - Quand vous dites que votre site ne répond pas. Je suppose, vous êtes verrouillé sur le côté JavaScript pas sur le côté serveur. Droite? Êtes-vous même en train de frapper le bloc de succès du côté client? Si vous voulez générer un rapport dans une autre fenêtre, pourquoi faites-vous un $ .ajaxPost? Pourquoi ne pas utiliser window.open() avec une URL aléatoire quel serveur comprend comment servir. –

+0

Je fais une fenêtre.ouvrir à l'url qui fait le travail et renvoie le pdf. Alors que cette fenêtre est en cours d'exécution et n'a pas retourné mon pdf, mon site est verrouillé, ce qui signifie que si je veux passer à une page différente, je ne peux pas. Si je fais une fenêtre.ouvrir à une page qui lance un ajaxPost, le même problème se produit. – smash51

Questions connexes