Getting a PDF from WCF to WCF - vb.net

Okay, here's what I have...
On one server, a WCF hosted in IIS. This one handles a bunch of stuff for an ASP.NET application which resides on the same server (mostly db calls). In the ASP app, there's an embedded iFrame which contains a PDF document viewer.
On another server, a WCF hosted in a Windows service. This one handles calls from the first WCF and kicks off a third-party document program which generates PDF files. For now, I have a dummy PDF file sitting on the C:\ drive to play with.
My mission: To somehow have a function in WCF #2 return a copy of the PDF document to WCF #1, which will save it to the local ASP application directory, so the embedded viewer can display it to a user.
So far I've tried having WCF #2 return a FileStream object but no luck there. I guess that's a big no-no in the WCF world (I'm a noob).
I have no idea how to accomplish this, most of my efforts are proving futile. How would YOU handle this? Anyone?
Thanks!

Have WCF2 take the PDF and return it as a byte array:
// fs is your FileStream
byte[] Data = new byte[fs.Length];
fs.Read(Data,0,fs.Length);
WCF1 calls WCF2 and reads the byte array, then saves it to disk
FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(buff);
bw.Close();

Thanks, Jason -- I did something similar. Thought I'd post for the next guy:
WCF #2:
Public Function GetPDF_Byte() As Byte() Implements IService1.GetPDF_Byte
Dim fs As New FileStream("C:\211LD.pdf", FileMode.Open, FileAccess.Read)
Dim ImageData As Byte() = New Byte(fs.Length - 1) {}
fs.Read(ImageData, 0, System.Convert.ToInt32(fs.Length))
fs.Close()
GetPDF_Byte = ImageData
End Function
And, WCF #1 which calls #2 and writes the file to disk:
Sub Main
Dim WCF As New ServiceReference1.Service1Client
Dim ByteData As Byte()
Dim oFileStream As System.IO.FileStream
ByteData = WCF.GetPDF_Byte
oFileStream = New System.IO.FileStream("C:\NewPDF.pdf", FileMode.Create)
oFileStream.Write(ByteData, 0, ByteData.Length)
oFileStream.Close()
End Sub
Hope that can help someone else!

Related

How to download file from SFTP in vb.net

I am trying to use the classes in Renci.SshNet.Sftp to download a file from an SFTP server with VB.NET. Here is my code:
Using client As New SftpClient("server", "test", "test")
client.Connect()
Dim list As List(Of SftpFile) = CType(client.ListDirectory(""), List(Of SftpFile))
'------------------------
For Each sFile As SftpFile In list
Console.WriteLine(sFile.Name)
client.DownloadFile("path", ????)
Next
client.Disconnect()
End Using
With this code I can connect to the server and see the file, but I can't download it. I don't know how to call the DownloadFile method.
The second parameter of the DownloadFile method takes a stream. So, you just need to create a new FileStream to write the downloaded data to a new file, like this:
Using fs As New FileStream(localFilePath, FileMode.CreateNew, FileAccess.Write)
client.DownloadFile(serverFilePath, fs)
End Using

How do you delete a file generated via webapi after returning the file as response?

I'm creating a file on the fly on a WebAPI call, and sending that file back to the client.
I think I'm misunderstanding flush/close on a FileStream:
Dim path As String = tempFolder & "\" & fileName
Dim result As New HttpResponseMessage(HttpStatusCode.OK)
Dim stream As New FileStream(path, FileMode.Open)
With result
.Content = New StreamContent(stream)
.Content.Headers.ContentDisposition = New Headers.ContentDispositionHeaderValue("attachment")
.Content.Headers.ContentDisposition.FileName = fileName
.Content.Headers.ContentType = New Headers.MediaTypeHeaderValue("application/octet-stream")
.Content.Headers.ContentLength = stream.Length
End With
'stream.Flush()
'stream.Close()
'Directory.Delete(tempFolder, True)
Return result
You can see where I've commented things out above.
Questions:
Does the stream flush/close itself?
How can I delete the tempFolder after returning the result?
On top of all this, it would be great to know how to generate the file and send it to the user without writing it to the file system first. I'm confident this is possible, but I'm not sure how. I'd love to be able to understand how to do this, and solve my current problem.
Update:
I went ahead with accepted answer, and found it to be quite simple:
Dim ReturnStream As MemoryStream = New MemoryStream()
Dim WriteStream As StreamWriter = New StreamWriter(ReturnStream)
With WriteStream
.WriteLine("...")
End With
WriteStream.Flush()
WriteStream.Close()
Dim byteArray As Byte() = ReturnStream.ToArray()
ReturnStream.Flush()
ReturnStream.Close()
Then I was able to stream the content as bytearraycontent:
With result
.Content = New ByteArrayContent(byteArray)
...
End With
On top of all this, it would be great to know how to generate the file and send it to the user without writing it to the file system first. I'm confident this is possible, but I'm not sure how. I'd love to be able to understand how to do this, and solve my current problem.
To do the same thing without writing a file to disk, you might look into the MemoryStream class. As you'd guess, it streams data from memory like the FileStream does from a file. The two main steps would be:
Take your object in memory and instead of writing it to a file, you'd serialize it into a MemoryStream using a BinaryFormatter or other method (see that topic on another StackOverflow Q here: How to convert an object to a byte array in C#).
Pass the MemoryStream to the StreamContent method, exactly the same way you're passing the FileStream now.

Stream PDF from a server to a web client vb.net

We have a servlet that will deliver PDF reports to a browser. We also have a IIS server running .net apps and we want to return the PDF from the servlet as a stream to the .Net app and then the .Net app would render the PDF to the browser (we are using this technique for reason I don't need to go into here). I am not much of a VB/ Visual Studio devloper by this code works by using a web request:
Dim BUFFER_SIZE As Integer = 1024
' Create a request for the URL.
Dim serveraction As String = "https://OurSeverName/ServletContext/Dispatch?action=ajaxRunReport&reportName="
Dim request As WebRequest = _
WebRequest.Create(serveraction + ReportName.Text)
' Get the response.
Dim res As WebResponse = request.GetResponse()
' Get the stream containing content returned by the server.
Dim dataStream As Stream = res.GetResponseStream()
' Open the stream using a BinaryReader for easy access.
Dim reader As New BinaryReader(dataStream)
' Read the content.
Response.ContentType = "application/pdf"
Response.AddHeader("content-disposition", "inline; filename=reportfile.pdf")
Dim bytes = New Byte(BUFFER_SIZE - 1) {}
While reader.Read(bytes, 0, BUFFER_SIZE) > 0
Response.BinaryWrite(bytes)
End While
reader.Close()
' Clean up the streams and the response.
Response.Flush()
Response.Close()
The only issue is, even though the code runs quickly, it takes 20-30 seconds to render the PDF in Chrome and IE but only a few seconds in FireFox. Any idea why there is a delay in rendering the PDF? Is there a better way to stream a PDF from one server to another?
There were just a couple of very subtle tweaks that were needed (and they seem pretty insignificant and non-intuitive to me).
I added the following before setting the content type:
Response.Clear()
Response.ClearHeaders()
And I added the following after reader.Close()
Response.End()
That was it. Now the PDF files stream nicely from the Java servlet to the IIS server and to the end user's browser.

WWW fileupload using VB.NET or Access/VBA

I would like to ask if there's a possibility to upload files to a webserver or an ftpserver using VB.NET or Access/VBA.
I think if there are possibilities - VB.NET is more powerful than Access/VBA, is that right?
Are there any chances using webservices?
And FTP? I think there must be a chance to copy files using VB.NET or Access via FTP ...
Is there anyone who could help me?
Thomas
Here is how you would do it using FTP:
Dim ftpRequest As System.Net.FtpWebRequest = DirectCast(System.Net.WebRequest.Create("ftp://ftp.myserver.com/foo.txt"), System.Net.FtpWebRequest)
ftpRequest.Credentials = New System.Net.NetworkCredential("username", "password")
ftpRequest.Method = System.Net.WebRequestMethods.Ftp.UploadFile
Dim myFile() As Byte = System.IO.File.ReadAllBytes("C:\somefile.txt")
Using ftpStream As System.IO.Stream = ftpRequest.GetRequestStream()
ftpStream.Write(myFile, 0, myFile.Length)
ftpStream.Close()
End Using

inserting remote image onto windows form in vb.net?

anyone have experience doing this?
What do you mean with remote? If you mean an image residing on a web server you can do like this:
Dim client As New System.Net.WebClient()
Dim stream As New System.IO.MemoryStream()
Dim data As Byte() = client.DownloadData("http://somewebsite/someimage.jpg")
client.Dispose()
stream.Write(data, 0, data.Length)
pictureBox.Image = Image.FromStream(stream)
Update
Marcs comment about rewinding the stream sparked my curiosity, so I looked into it, and thought I would add it here for completeness.
After writing the data to the stream, the stream's position will be pointing at the end of the stream and before reading from the stream, you would normally need to set the position to the beginning of the stream (stream.Position = 0). As it turns out, Image.FromStream will do this internally, and restore the stream position after loading the image.