Library tutorials & articles
Send Binary Data from ASP
- Introduction
- ReadBinaryFile Function
- ASP Modifications
Introduction
One of the more common tasks that we've performed is to send a existing document to the browser. For our client base, the most common document types include Adobe Acrobat (.pdf), Microsoft Word (.doc) and PKZip (.zip). Innately, it is not hard to get these files to the client. Simply using a Response.Redirect to the path for the document works. However, if the documents are kept in a location other than in the hierarchy underneath the web root, there are security considerations that need to be addressed. I don't know about you, but I'd rather look for alternates rather than knowingly expose my site to security holes. As well, if you client has associated the type of the downloaded file with an application on their computer, the document will be automatically opened. In many cases, I would rather have the user save the document in their field system.
Fortunately, we discovered a relatively straightforward option that was open
to us. With just a few lines of code, we can not only push binary data directly
from ASP, but also force the user to save the document onto their hard drive.
Related articles
Related discussion
-
Binary Studio | software development outsourcing Ukraine
by Soft Industry (5 replies)
-
asp Request.QueryString("dir")
by realmeteo (1 replies)
-
Looking for Senior Web Designer
by lwsmedia (0 replies)
-
Read eMails from Outlook express using ASP
by kumaravelu (1 replies)
-
Help to Call ASP function from onclick event in HTML to pass an array
by vka (0 replies)
Related podcasts
-
Scott Guthrie
Scott catches up with Scott Guthrie in an interview covering Ajax, Asp 2.0, extender controls, CSS adapters and more.
Hi, thanks for the code. i tested it in my ASP site.
i find however the code works for pdf files of around <80K size. Once the pdf files goes past 80K, the code bombs. All i see in the requesting browser is a 'page not found'.
Could it be related to the buffer size? Any idea?
Thanks, CK
Thanks for the code , maybe im being a little thick , but there is no mention of the
oUtilityObject referenced within this example code.
I managed to work it out using this article and another from here ..
http://www.developerfusion.com/show/2542
My working version of these two pieces of code is as follows ...
Function getBinaryFile(strFilePath)
Dim TypeBinary, oStream
TypeBinary = 1 ' Indicates a binary file
' Create the object
Set oStream = Server.CreateObject("ADODB.Stream")
' Open our file
oStream.Open
' Retreive binary data from the file
oStream.Type = TypeBinary
oStream.LoadFromFile strFilePath
' Return the binary data to the caller
getBinaryFile = oStream.read
' Destroy the ADO object
Set oStream = Nothing
End Function
sServerFile = Server.MapPath("/therealfilelocation/private/CTC012.pdf")
'sFile = "CTC012.pdf"
Response.Buffer = True
Response.Clear
' I want the file displayed within the browser so dont specify a filename
'Response.AddHeader "content-disposition", "attachment; filename=" & sFile
Response.ContentType = "application/pdf"
Response.BinaryWrite getBinaryFile(Server.MapPath("/therealfilelocation/private/CTC012.pdf"))
Response.end
%>
It is worth noting that when I specified a filename if the user chose the "open file" option instead of the "save file" option when prompted by Internet Explorer Acrobat reader displays the error "File Not Found" after IE has downloaded the data.
To get around this and to make the page look nicer , i commented out the filename part.
This means Internet Explorer Opens it via Acrobat in the browser (if configured).
I have not tested MACS or other Browsers yet.
Hope this helps someone.
gjohnson, I can think of two things.
1. check XP/IE security settings
2. Reinstall Adobe Reader.
I am having the exact same problem except my code works on a Windows XP computer but does not work in Windows 2000. In XP, acrobat opens in my web application and the pdf displays as it should. In 2000 using the exact same code, I get the "file download" message box. If I open the file, it opens as an aspx file showing the code that would have been used to generate the pdf. In fact, if I change the extension of the aspx file to pdf, it will open as it should in acrobat. Here is my code. Must be a bug in Windows or IE?
// Generate Crystal Report in PDF Format
ContainerContents Report = new ContainerContents();
Report.SetDataSource(ds);
CrystalDecisions.Shared.ExportOptions RptExportOptions =
new CrystalDecisions.Shared.ExportOptions();
RptExportOptions.ExportFormatType =
CrystalDecisions.Shared.ExportFormatType.PortableDocFormat;
CrystalDecisions.Shared.ExportRequestContext RptExportRequestContext =
new CrystalDecisions.Shared.ExportRequestContext();
RptExportRequestContext.ExportInfo = RptExportOptions;
System.IO.Stream RptStream = null;
RptStream = Report.FormatEngine.ExportToStream(RptExportRequestContext);
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = @"application/pdf";
Byte[] RptBuffer = new Byte[RptStream.Length];
RptStream.Read(RptBuffer, 0, (int)RptStream.Length);
Response.BinaryWrite(RptBuffer);
Response.End();
hi below is the code u sent
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/pdf";
Response.BinaryWrite(tPDF);
Response.End();
I know very well that I need to tPDF the content of pdf
can you please tell me how to store the content of the (let us say a1.pdf) pdf file in an array
so that i could pass it to the Response.BinaryWrite() method
rocko_hunk, sure it will throw an error on this line: Response.BinaryWrite(tFileName)
Because, tFileName is a string and you need to pass to Response.BinaryWrite method a binary array with proper PDF document.
In VS2003 I have the following code that works w/o problems:
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/pdf";
Response.BinaryWrite(tPDF);
Response.End();
Where tPDF is a binary array that contains a PDF document.
hi
i tried the followin code in a page using vb
Dim tFileName
tFileName = "1.pdf"
Response.Clear
Response.Buffer = True
'Response.AddHeader "Content-Disposition", "attachment; filename=" & tFileName
Response.ContentType = "application/pdf"
Response.BinaryWrite(tFileName)
but it throws error invalid cast
This worked for me....
Response.ContentType = "application/msword"
Response.OutputStream.Write(buffer, 0, buffer.length)....where buffer is a byte array.
Don't add a Response.AddHeader
Make sure the checkbox "Always ask before opening this type of file" in a download dialog isn't clicked.
Is it possible to output the content of the file in the browser instead of pushing
the file for downloading?
Thanks
I've created a database in Access 2000 and inserted my pdf files as OLE objects from within the database table view but when I get them out I have problems.
It seems as my files have extra information at the head of them. From what I gather a pdf file's binary data should start with '%PDF-' but the first couple of lines of mine seem to be as shown below. Is this an additional header or something that needs to be removed? (I got this data simply by removing the content type so that the binary data would be written as text).
The code works fine on the original file but not when I get it from the database.
Dim EAMSDatabase
Set EAMSDatabase = Server.CreateObject("ADODB.connection")
EAMSDatabase.Open ("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=e:\Inetpub\wwwroot\db.mdb")
Set objRS = EAMSDatabase.Execute("select pdf_object from articles where EntryId=1")
Response.Buffer = True
Response.Clear
Response.ContentType = "application/pdf"
Response.BinaryWrite objRS(0)
Response.end
EAMS_Database.Close
Any ideas?
abcdefghijklmnopqrstuvwxyz{|}~€Root Entryÿÿÿÿÿÿÿÿeʸü¡Ð…DESTУƒóÄOle ÿÿÿÿÿÿÿÿÿÿÿÿContentsÿÿÿÿ ²OlePres000ÿÿÿÿÿÿÿÿPþÿÿÿ !"#$%&'()*+,-./0123456789:þÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ«‹Lp4õ—XäÂzÈÈr“DÅ„öó~9šÇ¤]Ë;Ci’F7¿®êoÿÿÿÿÿÿÿÿì !’ ÿÿÿ¥A ƈ 9( @ÿÿÿ ¥9II3ò%9999444449999-]IŸ%49494444999-]Ÿ%%%%%%%%%%%%%%%$ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?ÿÿÿ!A Ff ‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ !"#$%&'()+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàþÿÿÿâãäåæçþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ%PDF-1.4 %âãÏÓ 143 0 obj<>stream xÚ¬WKoÛFæßèmâƒÁ}?‚ €,hàØM$9(>°2! uDƒ’ûÏ·ývWÑ‹JEE>ÃÝï›gv—B#!‰3A’“✤ åIIÚx’ŠŒ°$-¯H:²J’ôä”&ÅÈs y‘‹•„uÎ5¸q!Àä¶kuŒ¾X~ƒKâN¿ÝUx~/‹ÛÉt U‚6¦·‘ÉÊš¹ªç¼zÊ;÷óWá0xMÎ8u&5]U—ßPh”®RC†mÓôï ”s 9 Fíš·êG±u{xÞ +•¤Fû©9¯nŸáxpdÖÒBc ¡E&û5I've discovered strange thing, that this code doesn't work only on
machine where Visual Studio .NET 2005 (Whidbey) is installed.
I check it on several computers and it is true.
When I remove VS2005 and install only .NET-2.0,
which is supplied whith VS 2005. Everything goes well.
I use VS2005 alpha version which is little bit raw and has bugs
cboy, if you have Adobe Reader 6 on your system the browser plugin sometimes get screwed, re-run the install of Adobe Reader and try again, it should be fine.
-victor
I have same code and it doesn't work. White screen appear instead of PDF document :-(
I have same code and it doesn't work. White screen appear instead of PDF document :-(
This is a really bad function if you are sending files that are large, or where speed matters. For instance, I tested this function on a managed server where I received a download rate of around 4k per second. However, if I browsed directly to the file instead of having the function pass it to me I achieve speeds of around 80 to 100k per second. That is a considerable slowdown and it is very inneficient to send binary data one byte at a time
I am having the same problem where it wants to save the asp file, not the pdf file. ???
Does anyone know why this is?
I'm having the same exact problem.. " dialog box pops up in the browser it shows that it wants to download the file that is an ASP page it-self that contains this code, I can't get it to download PDF file. " I need help with this ASAP...
I"m using a third party software called "activepdf toolkit" to create the pdf and put it in memory. After it is done creating, i use this code to display the pdf to the browser.
response.ContentType = "application/pdf"
response.AddHeader "Content-Type", "application/pdf"
response.addHeader "Content-Disposition", "filename=part"&hour(Now)&""&minute(Now)&".PDF"
This works fine in IE 5.0 and above for windows.. but not on the mac version.
Thanks in advance..
Sorry to be stupid :-)
But i still have problems
I heve the code here after
The aim is to retrieve a dynamically generated PDF from another server by submitting a POST with the params.
The the result od this post, the PDF stream should be sent to the client browser.
if I do a response.BinaryWrite strValue, or a response.Write, i get this error message
'An unhandled data type was encountered.'
If a don't use a write but only have a look at the result I get
'status : 200statustext : OK ' so looks ok Here is the code
xmlhttp.send "TYPEDOC=STREAM"
strValue = xmlhttp.responseStream
'response.write "number of chars " & len(strValue) & "<br>"
response.write "status : " & xmlhttp.status
response.write "statustext : " & xmlhttp.statustext
The object comes with IE5.5 and higher (I believe). There is an XMLHTTP object that came with IE5, but it is single threaded, so not good for use in a server environment.
It runs on ASP. The technique used for ASP.NET is a different one. So while it could still be used, it is not the best approach to take.
Don't let the fact that has XML in the name fool you. I think the only reason that it's there is because the object is part of MSXML. It has no problems with binary streams.
The article can be found at http://www.developerfusion.com/show/3272/. Don't let the fact that it is written for Visual Basic slow you down. The same technique works in ASP.
THanks for the tip.
Were acn I get this object, and will it run on ASP or does it require ASP.Net ?
Being XML, is it able to handle binary streams ?
Can you post a link to the article ?
Best regards
The request from the web server to the application server could be done by using the ServerXMLHTTP object that is part of MSXML. That object allows you to programmatically make a request to a web server. I have an article on DevFusion that talks about how to do this. It's a synchronous call, so the response from the server is available to you immediately. This result could then be fed into the output stream from the web server back to the initial requester.
I haven't tried all of this together, but it should work
yes exactly.
The ASP page gets some parameters from a form.
These paramters are used to do a lookup in a database.
A url is created to connect to an application server. This server is only accessible from our web server, not from the clients browser.
So the asp page should issue an http request with an url with parameters to the application server who returns a pdf stream hi is building. This stream is then forwarded to the client browser
Is this possible ?
and how ?
I'm not exactly sure what you're asking. Are you saying that the server side code needs to retrieve the PDF file from a different URL before returning it in the Response stream?
Hi,
i've read your article and your solution works fine
allthough I do not understand why i am not asked if I want to save the document.
However my real problem is that I need to retrieve the PDF file first from a remote site
Any idea how to achieve this ?
best regards
better then to remove this line:
Response.AddHeader "content-disposition","attachement; filename=some.pdf"
is to change it to look like this
Response.AddHeader "content-disposition","inline; filename=some.pdf"
I am trying to create a sub at the dll level and just give it the strFilePath as a physical path...
Is there a way NOT to force it save/open but open it IN the IE? I tried removing the filename, but doesn't seem to work. I tried to remove the header and it worked. Is it a stable approach?
By the way, the Sub is configured only for jpg files. I will add the other files after I get this fixed.
Any help appreciated very much.
Thanks
Public Sub SendFile(ByVal strFilePath As String, _
Optional strFileName As String, _
Optional bForce As Boolean = False)
goResponse.Buffer = True
goResponse.Clear
If strFileName = "" Then _
strFileName = Mid(strFilePath, InStrRev(strFilePath, "\") + 1)
If bForce = False Then _
strFileName = ""
goResponse.AddHeader "content-disposition", "attachment; filename=" & strFileName
goResponse.ContentType = "image/jpeg"
Dim vStream As Variant
vStream = ReadBinaryFile(strFilePath)
goResponse.BinaryWrite (vStream)
goResponse.End
End Sub
Private Function ReadBinaryFile(ByVal strFileName As String) As Variant
Dim lFileLength As Long
Dim lFileNo As Long
Dim aBytes() As Byte
'On Error GoTo ErrHandler
lFileNo = FreeFile()
Open strFileName For Binary Access Read As #lFileNo
FileLength = FileLen(strFileName)
ReDim aBytes(lFileLength)
Get #lFileNo, , aBytes
Close #FileNo
ReadBinaryFile = aBytes
End Function
http://www.adobe.com/support/techdocs/93f2.htm
Is there different Adobe plug-ins for IE vs. Netscape?
Did you have to configure IE on the Mac to get this to work? Currently, when I run the code it downloads an asp page to the desktop instead of the pdf. The name of the asp file it is downloading is the name of the page I am running the script in.
Any assistance on the subject would be most appreciated. Thanks.
Jerry
I believe it was os9 but I wouldnt swear on it , but I do know it was IE on the MAC.
I also tested the code against netscape 6.2 and Opera 6.05 , working fine.
Regards
Scott.
Thanks Scott...
I've been struggling with this for weeks, reading various articles and trying different things.
Your code WORKS!!!
Very much appreciate you taking the time to post the solution.
thank you.
That's due to the
Response.AddHeader "Content-Disposition", "attachment; filename=" & tFileName
line. Remove it, and it should work fine.
To clarify, oUtilityObject simply contains the code on http://www.developerfusion.com/show/2235/2/, which is compiled into a VB DLL, and then called from the ASP code on the next page.
Thanks for the code , maybe im being a little thick , but there is no mention of the
oUtilityObject referenced within this example code.
I managed to work it out using this article and another from here ..
http://www.developerfusion.com/show/2542
My working version of these two pieces of code is as follows ...
Function getBinaryFile(strFilePath)
Dim TypeBinary, oStream
TypeBinary = 1 ' Indicates a binary file
' Create the object
Set oStream = Server.CreateObject("ADODB.Stream")
' Open our file
oStream.Open
' Retreive binary data from the file
oStream.Type = TypeBinary
oStream.LoadFromFile strFilePath
' Return the binary data to the caller
getBinaryFile = oStream.read
' Destroy the ADO object
Set oStream = Nothing
End Function
sServerFile = Server.MapPath("/therealfilelocation/private/CTC012.pdf")
'sFile = "CTC012.pdf"
Response.Buffer = True
Response.Clear
' I want the file displayed within the browser so dont specify a filename
'Response.AddHeader "content-disposition", "attachment; filename=" & sFile
Response.ContentType = "application/pdf"
Response.BinaryWrite getBinaryFile(Server.MapPath("/therealfilelocation/private/CTC012.pdf"))
Response.end
%>
It is worth noting that when I specified a filename if the user chose the "open file" option instead of the "save file" option when prompted by Internet Explorer Acrobat reader displays the error "File Not Found" after IE has downloaded the data.
To get around this and to make the page look nicer , i commented out the filename part.
This means Internet Explorer Opens it via Acrobat in the browser (if configured).
I have not tested MACS or other Browsers yet.
Hope this helps someone.
Dim tFileName
tFileName = "web_report.pdf"
Response.Clear
Response.Buffer = True
Response.AddHeader "Content-Disposition", "attachment; filename=" & tFileName
Response.ContentType = "application/pdf"
Response.BinaryWrite tPDF
it doesn't open a PDF file in my browser window?
can you please help!?
I need it ASAP.
Thank you!
?????????? ?? ?? ??????? http://www.thaiirc.com
I was wondering. Is there any settings I need to do on the mac to enable the opening of a pdf. I am running MAC OS X , IE 5.2. I was reading online for all the settings for the mac browser to open up a pdf but it doesn't work. Any help is appreciated. Thanks
<%@ Language=JavaScript %>
<%
// some code to get binary pdf.
Response.Clear();
Response.Buffer = true;
Response.AddHeader("Content-Disposition", "attachment; filename=" + tFileName);
Response.ContentType = "application/pdf";
Response.BinaryWrite(tPDF);
%>
Make sure before these lines you don't write anything into response and remove all html code from this page, try this by only leaving server side code, this is how I got mine working.
good luck.
I'm having the same exact problem.. " dialog box pops up in the browser it shows that it wants to download the file that is an ASP page it-self that contains this code, I can't get it to download PDF file. " I need help with this ASAP...
I"m using a third party software called "activepdf toolkit" to create the pdf and put it in memory. After it is done creating, i use this code to display the pdf to the browser.
response.ContentType = "application/pdf"
response.AddHeader "Content-Type", "application/pdf"
response.addHeader "Content-Disposition", "filename=part"&hour(Now)&""&minute(Now)&".PDF"
This works fine in IE 5.0 and above for windows.. but not on the mac version.
Thanks in advance..
I followed the example, but when the dialog box pops up in the browser it shows that it wants to download the file that is an ASP page it-self that contains this code, I can't get it to download PDF file.
Please help!
Nevermind, I found it.
Thanks.
Use this code and you do not need any special components or any other techniques.
Set fs = CreateObject("Scripting.FileSystemObject")
Set a = fs.OpenTextFile("c:\inetpub\file.gif", 1, 0)
Do While a.AtEndOfStream <>True
retstring = a.Read(1)
response.binarywrite(chrb(asc(retstring)))
loop
a.close
Off course this will slow your server because it must convert (in example) 10 000 of bytes, but i do not think that you will feel it (also with big files).
Have you tried adding another header of the form 'Content-Disposition: filename="fname"' to the request?
Yes, I did use "octet-stream" as the content type. But the Mac IE 5.1 still does not recognize it as a "File->Save As" action. Is there a way at all to make this work with the Mac? It seems very happy on Windows.
So I've been cogitating on this for awhile. There is nothing sophisticated in the HTML code (at least, not from a standards perspective), so the answer has to lie elsewhere. Had me stumped. But as I was showering this morning, it struck me. Maybe it has something to do with the content type values. I don't know what they are supposed to be for the Macintosh. You might want to try setting it to 'application/octet-stream'. That is sort of the default type for use in Mac's (I believe).
Hope this helps.
So I've been cogitating on this for awhile. There is nothing sophisticated in the HTML code (at least, not from a standards perspective), so the answer has to lie elsewhere. Had me stumped. But as I was showering this morning, it struck me. Maybe it has something to do with the content type values. I don't know what they are supposed to be for the Macintosh. You might want to try setting it to 'application/octet-stream'. That is sort of the default type for use in Mac's (I believe).
Hope this helps.
I don't have immediate access to a Mac to try this out. Let me do some digging and get back to you.
Hi,
I tried your tutorial. Works great on Windows and IE 5.5+. But my Mac running IE 5.1 doesn't work. The Save As dialog did not show up on Mac.
Please help.
This thread is for discussions of Send Binary Data from ASP.