How can this be accomplished using ASP.NET MVC 3? Let's make a small use case to illustrate our goal and then dig into some sample code:
- Load a "download" page.
- After a 2 second delay, prompt the user to save a PDF document. (In this case we do not want the browser to use any plugins to render the document).
$(function() { $(window).bind('load', function() { $("div.downloadProject").delay(2000).append( ''); }); });Be sure to include the following in our Html:
This code inserts an iframe into the DOM after a 2 second delay. This iframe is responsible for triggering the prompt to save the PDF. Unfortunately, I could not get this to work in ASP.NET MVC 3 by just referencing the path to the PDF in the source attribute of the iframe. To solve this, I added an action (and associated routing rules) to my Home controller for downloading the PDF as a FileContentResult.
public ActionResult DownloadPDF() { return File("~/FileToDownload.pdf", "application/pdf", "FileToDownload.pdf"); }Including the third parameter in the "File" method adds the "Content-Disposition: attachment;" header - this forces the browser to handle the file using the save dialog prompt instead of any browser plugins.
To finish up, we'll revisit the jQuery code we started with and point the iframe to our new action instead of the direct path to the PDF.
$(function() { $(window).bind('load', function() { $("div.downloadProject").delay(2000).append( ''); }); });