views:

120

answers:

2

Ok, so I have an action method that generates a PDF and returns it to the browser. The problem is that instead of automatically opening the PDF, IE displays a download prompt even though it knows what kind of file it is. Chrome does the same thing. In both browsers if I click a link to a PDF file that is stored on a server it will open up just fine and never display a download prompt.

Here is the code that is called to return the PDF:

public FileResult Report(int id)
{
    var customer = customersRepository.GetCustomer(id);
    if (customer != null)
    {
        return File(RenderPDF(this.ControllerContext, "~/Views/Forms/Report.aspx", customer), "application/pdf", "Report - Customer # " + id.ToString() + ".pdf");
    }
    return null;
}

Here's the response header from the server:

HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Thu, 16 Sep 2010 06:14:13 GMT
X-AspNet-Version: 4.0.30319
X-AspNetMvc-Version: 2.0
Content-Disposition: attachment; filename="Report - Customer # 60.pdf"
Cache-Control: private, s-maxage=0
Content-Type: application/pdf
Content-Length: 79244
Connection: Close

Do I have to add something special to the response to get the browser to open the PDF automatically?

Any help is greatly appreciated! Thanks!

+4  A: 
Response.AppendHeader("Content-Disposition", "inline; filename=foo.pdf");
return File(...
Darin Dimitrov
+2  A: 

On the HTTP level your 'Content-Disposition' header should have 'inline' not 'attachment'. Unfortunately, that's not supported by the FileResult (or it's derived classes) directly.

If you're already generating the document in a page or handler you could simply redirect the browser there. If that's not what you want you could subclass the FileResult and add support for streaming documents inline.

public class CustomFileResult : FileContentResult
   {
      public CustomFileResult( byte[] fileContents, string contentType ) : base( fileContents, contentType )
      {
      }

      public bool Inline { get; set; }

      public override void ExecuteResult( ControllerContext context )
      {
         if( context == null )
         {
            throw new ArgumentNullException( "context" );
         }
         HttpResponseBase response = context.HttpContext.Response;
         response.ContentType = ContentType;
         if( !string.IsNullOrEmpty( FileDownloadName ) )
         {
            string str = new ContentDisposition { FileName = this.FileDownloadName, Inline = Inline }.ToString();
            context.HttpContext.Response.AddHeader( "Content-Disposition", str );
         }
         WriteFile( response );
      }
   }

A simpler solution is not to specify the filename on the Controller.File method. This way you will not get the ContentDisposition header, which means you loose the file name hint when saving the PDF.

Marnix van Valen