2016-07-03 2 views
0

Ich habe eine Aktion, die ein .pdf Dokument generiert und es zurückgibt, um es inline im Browser anzuzeigen. Das Problem besteht darin, dass der Browser eine zweite Anfrage an die gleiche Aktion stellt, die dazu führt, dass die App bei jeder Generierung der Datei zweimal ausgeführt wird. Das habe ich.MVC 4 - Das Zurücksenden der PDF-Datei aus der Aktion veranlasst den Browser, die Aktion zweimal zu laden

public ActionResult GeneratePDF(string id, int rp = 1, string info = "") 
{   
    var doc = _service.GeneratePDF(id, rp, info); 
    var cd = new System.Net.Mime.ContentDisposition 
    { 
     FileName = $"{id}.pdf", 
     Inline = true, 
     Size = tickets.Length 
    }; 
    Response.AppendHeader("Content-Disposition", cd.ToString()); 
    return File(doc, MimeMapping.GetMimeMapping(cd.FileName)); 
} 

_service.GeneratePDF erzeugt das PDF im Speicher iTextSharp und MemoryStream Objekt mit einer Aktion byte[]

Die GeneratePDF Rückkehr von einem Link auf eine andere Seite aufgerufen wird:

<a href="SomeController/GeneratePDF/1234?rp=1" target="_blank">View Document</a>

Das einzige, was Auf dieser neuen Browser-Registerkarte wird das Dokument .pdf angezeigt.

Ich habe auf verschiedenen Browsern (Chrome, IE, FF) versucht und das Ergebnis ist das gleiche, die .pdf Datei wird ordnungsgemäß auf dem Browser angezeigt, aber es erfordert einen zweiten Aufruf der gleichen Aktion. Irgendwelche Ideen, wie verhindert werden kann, dass der Browser die Aktion zweimal aufruft? Fehle ich etwas an den Headern?

Edit: Browser Verhalten enter image description here erste Anforderung ist normal und vervollständigt mit keinem Problem. Die zweite Aktion führt die Aktion aus, aber der Browser (oder etwas anderes) bricht diese Anfrage ab.

+0

die Aktion angezeigt wird uns nicht identifizieren helfen, warum es zweimal genannt zu werden. Das ist, als würde man uns eine Kugel zeigen und uns bitten, den Schützen zu identifizieren! – DavidG

+0

@DavidG Welche anderen Informationen sollte ich bereitstellen? – Mike

+0

Aktion wird zweimal ausgeführt, Datei wird jedoch nur einmal generiert. Ist das richtig? –

Antwort

0

Haben Sie eine Lösung gefunden? Ich habe das gleiche Problem. Eine Aktion erzeugt eine PDF-Datei. Diese Aktion wird zweimal aufgerufen.

Ich habe die Content-Disposition zu Befestigung statt Inline und es ist in Ordnung, die Aktion nur einmal aufgerufen wird. Aber natürlich wird die Datei gespeichert und nicht im Browser angezeigt.

+0

Ich habe das gleiche getan. Habe immer noch nicht die richtige Antwort gefunden. – AdrianCogiel

0

Ich hatte genau das gleiche Problem. Denken Sie daran, ich habe KEINE IDEE, wie man das tatsächlich verhindern kann, aber ich habe mir eine Arbeit ausgedacht, wenn das hilft. Ich schaute auf beide Anfragen und bemerkte, dass der Referrer der zweiten "falschen" Anfrage die Controller-Aktionsroute selbst ist (seltsam). Mir ist aber auch aufgefallen, dass die zweite Anfrage vom Client getrennt war und bereits eine Kündigung angefordert wurde (ich vermute wohl, warum alles im Browser o.k. aussieht). Ich bin mir sicher, mit diesen Informationen und einem besseren Verständnis von MVC/Routen könnte ich das wahrscheinlich irgendwann erklären.

Wie auch immer, was ich getan habe, war meine PDF-Generierung/Display-Code in einem Scheck für die Client-Verbindung zu wickeln. Wenn die Verbindung getrennt wird, gebe ich ein leeres Suchergebnis zurück. Wie ich schon sagte, totaler Workaround, aber es hat mich überholt, bis jemand, der schlauer ist als ich, erklären kann, was passiert und wie man es beheben kann.

if (Response.IsClientConnected) 
 
{ 
 
    if (pdfId == 0) 
 
    { 
 
     var model = _service.GetViewData(client, id); 
 
     model.StaffName = CTCHelper.GetStaffName(model.StaffId); 
 
     pdfId = _service.SavePDF(model, ControllerContext); 
 
    } 
 
    var data = _service.GetPDF(pdfId); 
 
    var mimeType = "application/pdf"; 
 
    Response.AppendHeader("Content-Disposition", "inline; filename=TESI.pdf"); 
 

 
    return File(data, mimeType); 
 
} 
 
Response.End(); 
 
return new ViewResult();