467,885 Members | 1,292 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 467,885 developers. It's quick & easy.

PDF request service


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
Nov 23 '05 #1
  • viewed: 2408
Share:
1 Reply
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

Nov 23 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

8 posts views Thread by turnit \(removethis\) | last post: by
1 post views Thread by Kevin C | last post: by
3 posts views Thread by Codex Twin | last post: by
4 posts views Thread by Jit Prasad | last post: by
reply views Thread by MrMoon | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.