views:

503

answers:

5

Hi, I am trying to do pretty much the same, as is for example on sourceforge. After a user creates some data, i generate a file and i want it to be offered to him after a page loads. However, i know almost nothing about javascript and simple copy paste of

< script type="text/javascript">
var download_url = "http://downloads.sourceforge.net/sourceforge/itextsharp/itextsharp-4.1.2-dll.zip?use_mirror=dfn";


function downloadURL() {
    if (download_url.length != 0 && !jQuery.browser.msie){
        window.location.href = download_url;
    }
}

jQuery(window).load(downloadURL);

< /script>

is not enough. It is important for the user to download the file, so how to do that?

A question related to the previous is - where to store the file i created? Once while using the asp.net development server and then on the real iis server? And how should this address look? When i tried

setTimeout("window.location.href='file://localhost/C:/Downloads/file.pdf'", 2000);

i was getting nothing, with http an error of unknown adress.

+1  A: 

you're asking the user's browser to look for a file on their own computer... that you're trying to save there.

you could use something like:

window.location.href='http://www.yourServer.com/generatePDF.asp?whatever=whatever'

where http://www.yourServer.com/generatePDF.asp?whatever=whatever is what is generating the pdf file for the user

Jonathan Fingland
+1  A: 

On the server, you have to set the content disposition in the response header to "Attachment" as described in these answers.

If you do that, the download will not affect the page that is currently displayed in the browser. So, if you initiate a request in Javascript that gets an attachment, the browser will leave the page alone, and the user will see a message box with the Open/Save/Cancel question.

cdonner
A: 

A couple of different things. First, since you are using MVC, create an action that actually generates the file and returns it as a FileResult. The file can be an actual file on the server, but it can also be generated dynamically -- say in a MemoryStream -- and the FileResult created from that. Set the content to application/octet-stream or the actual file type if it's not one that will render in the browser via a plugin. Second, don't generate the file in the action that renders the page, but rather call the action that generates the FileResult from that page using the technique you've referenced (though it looks like they are doing something different for IE). If the MIME type is not one that can be rendered it will be downloaded.

public ActionResult GenerateFile( string value, int other )
{

   MemoryStream file = new MemoryStream();
   ...

   return File( file, "application/octet-stream" );
}
tvanfosson
The problem is, i am using itext library to generate the pdf. Therefore the file to be created is of type Document, which is not compatible with FileResult. But if there is another way to generate a pdf..?
Trimack
+1  A: 

See Haack's DownloadResult example. It explains (I think) exactly what you're truing to do. Except you would provide the timeout call with your download action url.

hometoast
+1  A: 

You can create your own PdfResult which extends ActionResult like this:

public class PdfResult : ActionResult
{
    public byte[] Content { get; set; }
    public string FileName { get; set; }

    public override void ExecuteResult(ControllerContext context)
    {
        var response = context.HttpContext.Response;
        response.AddHeader("content-disposition", "attachment; filename=" + this.FileName);
        response.AddHeader("content-length", this.Content.Length.ToString());
        response.ContentType = "application/pdf";

        using (MemoryStream memoryStream = new MemoryStream(this.Content))
        {
            memoryStream.WriteTo(response.OutputStream);
        }

        response.End();
    }

Then in your action you can simply return the file as follows:

    public ActionResult Pdf(string param1...)
    {
        var content = GeneratePdf(); //etc
        var fileName = AssignFileName();

        return new PdfResult { Content = content, FileName = fileName + ".pdf" };
    }
Sam Wessel