Link to home
Start Free TrialLog in
Avatar of HLRosenberger
HLRosenbergerFlag for United States of America

asked on

How to stream a PDF

I want to stream a PDF file from server to client browser.  How do I do this?  

Currently, I converting an in memory stream of the file to a byte array, and then using  Response.BinaryWrite(FileContent) and  Response.End() to stream the contents to the client.  On the client I'm using and XMLHttpRequest object.  (I see the streamed data during debug in the XMLHttpRequest responseText).   I then convert responseText to a blob and then use window.navigator.msSaveOrOpenBlob.      However, the PDF is somehow corrupt and I cannot open using Acrobat.  I tried to copy/paste the contents of the responseText using Notepad and then saving as a PDF.  I get a message that the data contains Unicode characters.  Is this maybe the issue?  Do I have to encode the data before I stream in order to handle the Unicode characters?  

Thanks!


 var blob = Blob([xhr.responseText], { type: "application/pdf" });
 window.navigator.msSaveOrOpenBlob(blob, "myairport.pdf");
Avatar of David Johnson, CD
David Johnson, CD
Flag of Canada image

Since it is binary you need to base64 encode it and decode it.
Avatar of HLRosenberger

ASKER

so, a stream is a byte array, correct?  so I would need to convert the byte array to a string while base64 encoding it, then convert that back to a byte array, then stream it?
ah, if I convert to base64, I need to use Response.write instead of Response.WriteBinary.   Correct?  I'm getting a PDF that I can now open, but it's blank.  Something not quite correct.
is the PDF stored as a file on the server ?

if so, i use an ashx handler to present PDF to the browser.

        string filepath = mySrc + myURL;
        // Create New instance of FileInfo class to get the properties of the file being downloaded
        FileInfo file = new FileInfo(filepath);

        // Checking if file exists
        if (file.Exists)
        {
            string errLoc = "begin";
            try
            {
                // Clear the content of the response
                context.Response.ClearContent();

                //Response.AddHeader("Content-Disposition", String.Format("attachment; filename={0}", file.Name));
                if (OpenInBrowser)
                {
                    AddContentDispositionHeader(context.Response, "inline", file.Name);
                }
                else
                {
                    //show as separate application/download
                    AddContentDispositionHeader(context.Response, "attachment", file.Name);
                }
                // Add the file size into the response header
                context.Response.AppendHeader("Content-Length", file.Length.ToString());

                errLoc = "set contenttype";
                // Set the ContentType
                context.Response.ContentType = ReturnFiletype(file.Extension.ToLower());

                errLoc = "transmit file";
                // Write the file into the response 
                context.Response.TransmitFile(file.FullName);

                errLoc = "end response";
                // End the response
                //context.Response.End();
                context.Response.Flush();

                context.ApplicationInstance.CompleteRequest();

                context.Response.End();
            }
            catch(Exception ex)
            {
                string eMsg = "Failed to show file @ " + errLoc + "<hr>";
                eMsg += ex.Message;
                if (ex.Message == "Thread was being aborted.")
                {
                    //ignore
                }
                else
                {
                    eMsg += ex.ToString();
                    eMsg += ex.InnerException.ToString();
                    context.Response.ClearContent();
                    context.Response.ContentType = "text/html";
                    context.Response.Write("<H1>Doc File Display</h1>\n <h3>ERROR: during display/file access.... </h3>\n ");
                    context.Response.Write(eMsg);
                    context.Response.End();
                }
            }
        }

        else
        {
            context.Response.ContentType = "text/html";
            context.Response.Write("<H1>Doc File Display</h1>\n <h3>ERROR: file not found.... \n ") ;
            context.Response.Write("==" + file.FullName + "== </H3>\n");
            context.Response.Write("Please advise the project document controller");
        }
    }


  //return the filetype to tell the browser. 
    //defaults to "application/octet-stream" if it cant find a match, as this works for all file types.
    public static string ReturnFiletype(string fileExtension)
    {
        switch (fileExtension)
        {
            case ".htm":
            case ".html":
            case ".log":
                return "text/HTML";
            case ".txt":
                return "text/plain";
            case ".doc":
                return "application/ms-word";
            case ".tiff":
            case ".tif":
                return "image/tiff";
            case ".asf":
                return "video/x-ms-asf";
            case ".avi":
                return "video/avi";
            case ".zip":
                return "application/zip";
            case ".xls":
            case ".csv":
                return "application/vnd.ms-excel";
            case ".gif":
                return "image/gif";
            case ".jpg":
            case ".jpeg":
                return "image/jpeg";
            case ".bmp":
                return "image/bmp";
            case ".wav":
                return "audio/wav";
            case ".mp3":
                return "audio/mpeg3";
            case ".mpg":
            case ".mpeg":
                return "video/mpeg";
            case ".rtf":
                return "application/rtf";
            case ".asp":
                return "text/asp";
            case ".pdf":
                return "application/pdf";
            case ".fdf":
                return "application/vnd.fdf";
            case ".ppt":
                return "application/mspowerpoint";
            case ".dwg":
                return "image/vnd.dwg";
            case ".msg":
                return "application/msoutlook";
            case ".xml":
            case ".sdxl":
                return "application/xml";
            case ".xdp":
                return "application/vnd.adobe.xdp+xml";

            default:
                return "application/octet-stream";
        }
    }

Open in new window

it's in a stream.
ASKER CERTIFIED SOLUTION
Avatar of Robberbaron (robr)
Robberbaron (robr)
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks.