First, you need to change your line...
Response.ContentType = "application/octet-stream"
..to...
Response.ContentType = "application/pdf"
Then, you have to actually write the byte array to the stream, like so...
Response.BinaryWrite(PDFData)
Then, you finish it off...
Response.Flush()
Response.Close()
If you still have problems, try changing the .AddHeader statement to read
'inline' instead of 'attachment'
"evilme" <ev****@discussions.microsoft.com> wrote in message
news:D7**********************************@microsof t.com...
greetings and salutations, o smarter than i.
i've been working on a solution to secure the delivery of pdfs to client
browsers. we're introducing an public-website element, so i've decided to
use
a webservice on the internal application webserver to pass a pdf as a byte
array to a public webserver outside the LAN, where it can be forwarded on
the
response to the client browser.
i could use some advice how to improve this: i'm not entirely satisfied
with
the memory useage--i'm trying to shy away from taking on making a ISAPI
extention if i can get this efficient enough as is.
more vexingly, every so often, a local user will experience an error where
the PDF is never saved/opened after they make their choice on the file
open/save dialog. further, msie's progress meter remains and looks like
it's
very slowly filling (or timing out) even after the pdf has successfully
been
saved/opened--is there a final signal i'm failing to send to the
browser..?
I designed the web service as follows:
Public Class DocumentRequest
Inherits System.Web.Services.WebService
Private EXAMPLE_DIR As String =
Server.mappath("/ExportedPDFs/ExampleSheets/")
Private Function BinaryGetPDFDocument(ByVal FileDIR As String, ByVal
FileNum As String) As Byte()
Dim FileStreamIn As New System.IO.FileStream(FileDIR + FileNum +
".pdf", System.IO.FileMode.Open, System.IO.FileAccess.Read,
System.IO.FileShare.Read)
Dim PDFData(FileStreamIn.Length) As Byte
Dim i As Integer = FileStreamIn.Read(PDFData, 0,
CInt(FileStreamIn.Length))
While (i < CInt(FileStreamIn.Length))
System.Threading.Thread.Sleep(200)
End While
FileStreamIn.Close()
Return PDFData
End Function
Private Function CheckExistsPDFDocument(ByVal FileDIR As String, ByVal
FileNum As String) As Boolean
Try
If (System.IO.File.Exists(FileDIR + FileNum + ".pdf")) Then
Return True
Else
Return False
End If
Catch
Return False
End Try
End Function
<WebMethod()> _
Public Function GetExampleSheet(ByVal FileNum As String) As Byte()
Return BinaryGetPDFDocument(EXAMPLE_DIR, FileNum)
End Function
<WebMethod()> _
Public Function CheckExistsExampleSheet(ByVal FileNum As String) As
Boolean
Return CheckExistsPDFDocument(EXAMPLE_DIR, FileNum)
End Function
End Class
and i wrote a consume function as follows:
Friend Sub PushPDFtoClient(ByRef Response As System.Web.HttpResponse,
ByVal FileNum As String, ByVal TYPE As String)
Dim ws As New PDFRequest.DocumentRequest
Dim PDFData() As Byte
Try
If (TYPE = "EXAMPLE") Then
PDFData = ws.GetExampleSheet(FileNum)
End If
Catch ex As Exception
'EDITED - removed some private logging functions
Response.Write("<script language=""javascript""
type=""text/javascript"">alert('There was an unexpected error accessing
the
PDF')</script>")
Exit Sub
End Try
Dim ms As System.IO.MemoryStream = New
System.IO.MemoryStream(PDFData)
Response.Clear()
Response.ContentType = "application/octet-stream"
Response.AddHeader("Content-Disposition", "attachment; filename=" &
TYPE & "-" & FileNum & ".pdf; size=" & PDFData.Length.ToString)
Response.AddHeader("Content-Length", PDFData.Length.ToString)
Response.Flush()
Dim chunkSize As Integer = 1024
Dim i As Integer
For i = 0 To PDFData.Length Step chunkSize
If (Not Response.IsClientConnected) Then
Exit For
End If
Dim size As Integer = chunkSize
If (i + chunkSize >= PDFData.Length) Then
size = (PDFData.Length - i)
End
Dim chunk(size - 1) As Byte
ms.Read(chunk, 0, size)
Response.BinaryWrite(chunk)
Response.Flush()
Next
ms.Close()
Response.End()
End Sub