1

I have list of PDF files on website (asp.net webforms). i want to open them with Save As option rather than it downlaods directly.

I tried to add download property to the link which didn't work. only was around seems to be HTTPHandler for *.pdf request.

I saw a piece of code for MVC based example here

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

How can i convert this to HTTPHandler in as.net webform so that it open pdf files with Save As option.

I want to do it in a way so that when ever user click on any pdf file at that time Handler should come into action.

OR

I can create another file handlePDF.aspx and write code there also and will change link of pdf file to below

<a href="handlePDF.aspx?file=file1.pdf">File One </a>
Community
  • 1
  • 1
Learning
  • 19,469
  • 39
  • 180
  • 373

2 Answers2

2

If what you are trying to do is when they click on the file download link it pops up with save as or open dialog box, this is to do with the user's browser configuration. In the case of PDF's i believe Firefox has open in tab as the default option. If you try to push the file as a file stream it will more than likely just load it in a new tab as well.

tl;dr: Client side issue

Byren Higgin
  • 552
  • 4
  • 13
  • Cant use that option as it is client request we cant configure each browser. I want to avoid it as it is heavy on server as sending out pdf as a stream take server resources. – Learning May 18 '16 at 03:52
  • Have you tried the `File One ` approach? – Byren Higgin May 18 '16 at 04:01
  • I have to create `handlePDF.aspx` first otherwise it will get page not found error. I have already tried `download target="_blank"` previously on the link it doesn't work – Learning May 18 '16 at 04:05
1

You're on the right track. Serving PDF files are usually handled by an HttpHandler. That is, unless they can be served straight from the file system by the StaticHandler...

The key thing that is needed in order for the browser to raise the "Open or save" dialog is the Content-Disposition header in the response.

Here is an (untested) implementation that should get you on the right track:

public void ProcessRequest(HttpContext context)
{
    string fileName = context.Request.QueryString["file"];
    if(fileName == null || fileName == "")
    {
        throw new ArgumentException("The file argument cannot be null or empty");
    }

    // fetch file here from db/filesystem/other storage
    byte[] fileBytes = LoadFileBytes(fileName);

    context.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
    context.Response.ContentType = "application/pdf";
    context.Response.BinaryWrite(fileBytes);
}

If you want to avoid buffering the whole file in memory, this might also work (requires .Net 4.0 for the CopyTo method on the stream):

public void ProcessRequest(HttpContext context)
{
    string fileName = context.Request.QueryString["file"];
    if(fileName == null || fileName == "")
    {
        throw new ArgumentException("The file argument cannot be null or empty");
    }

    // fetch file stream from db/filesystem/other storage
    Stream fileStream = GetFileStream(fileName);

    context.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
    context.Response.ContentType = "application/pdf";
    fileStream.CopyTo(context.Response.OutputStream);
}
user1429080
  • 9,086
  • 4
  • 31
  • 54