Share via


Open pdf-file in new browser window - via controller or javascript?

Question

Tuesday, October 4, 2011 9:22 AM

Hi!

I am very new to MVC so please don't judge me in advance 
I have a pdf-file, or a bytearray, which I want to open in a new browser window. I would basically like to open it in the controller but I didn't know how to, so I tried to pass the result to the javascript and open the browser window there, which I couldn't get to work either. 

Controller:

public ActionResult ViewPDF()
{
     byte[] pdfFile;
     pdfFile = GetByteArray();

   var fileName = "C:\\Temp\\TestPDF.pdf";
   var fileStream = new System.IO.FileStream(fileName, System.IO.FileMode.Create, System.IO.FileAccess.Write);
   fileStream.Write(pdfFile, 0, pdfFile.Length);
   fileStream.Close();

      return File( pdfFile, "application/pdf" );

the bytearray stores perfectly as a pdf and is possible to open from harddrive. But then I want to open it in the browser (via controller or javascript doesn't matter)

In my js-file I have a function:

function viewPDFTest() {
        $.ajax({
            url: '/ViewPDF',
            type: "GET",
            documenttype: "application\pdf",
            async: false,
            cache: false,
            success: function (result) {
                window.open(result); ,
            error: function () { alert("Unable to view pdf");  }
        });

Now the window.open(result) doesn't work at all, it locks the application. Is it even possible to do like this? All examples I've found so far is opening a link.. or doing it in an aspx-page. And I would very much like to use the result instead, since I don't know the filename of the pdf from time to time and also don't want to save files on the hard drive. I don't have to use the javascript if there is a way to open the pdf directly from the Controller. Any suggestions would be much appriciated! :)

All replies (6)

Friday, October 7, 2011 6:54 PM âś…Answered

You need to store FileStream, MimeType and FileName in database then return file:

        /// <summary>
        /// Gets the attachment.
        /// </summary>
        /// <param name="id">Attachment ID</param>
        /// <returns>File</returns>
        public ActionResult GetAttachment(int id)
        {
            var file = _attachmentRepository.GetAttachmentByID(id);
            Response.AppendHeader("Content-Disposition", "inline; filename=" + file.FileName); //this opens file in tab when you return it
            return File(file.FileStream,file.FileMimeType,file.FileName);        
        }

/// <summary>
        /// Gets the attachment by ID.
        /// </summary>
        /// <param name="id">Attachment id.</param>
        /// <returns></returns>
        public Attachment GetAttachmentByID(int id)
        {
            return entities.Attachment.SingleOrDefault(a => a.AttachmentID == id);
        }

i'm using EF to acces my data layer but it would be the same. If you sometimes don't have a file name then before storing in database add a dummy file name. You can check Content-Disposition here: http://msdn.microsoft.com/en-us/library/ms526989(v=EXCHG.10).aspx


Tuesday, October 4, 2011 9:32 AM

Now the window.open(result) doesn't work at all, it locks the application

var fileName = "C:\Temp\TestPDF.pdf";

Are you sure asp.net have access to this folder?

And who is "GetBytearray" ?


Tuesday, October 4, 2011 9:47 AM

No, asp.net does not have access to this folder, it was just a test view the pdf-file, and this is why I return the result with the bytearray in

"return File (pdfFile, "application/pdf")"

and the GetByteArray is just a dummy function for retrieving my bytearray from the database. 

Sorry for my blurry description 


Tuesday, October 4, 2011 12:08 PM

you can not display a pdf downloaded via ajax in a window. try:

function viewPDFTest() {
    window.open('@Url.Action('"viewpdf")',"PDFViewer");
}

Tuesday, October 11, 2011 4:34 AM

That might work but I don't have access to the database so I can't store it there, neither do I want to store in on disk before open/save in browser. I partly solved it with html.beginform in the cthml-file, it now downloads the pdf in the browser. Problem is that if an error occurs when creating the bytearray, I would like to return a partial view instead of a byte array, and I haven't found a way to make that work yet. But I guess thats another question 

Thanks for all your help, you got me on the right track to solving this!


Tuesday, October 11, 2011 10:00 AM

Make a try-catch block and if an error accurs when creating bytearray put in catch block return PartialView(), if no error accurs then return bytearray.