VB.Net: Cannot download stream file generated with ZipOutputStream - vb.net

I'm trying to zip a set of pdf files and send to client as download.
No matter what combinations of Response settings I try, the code doesn't throw any exception and apparently the zip file stream is created fine, but the file is not sent to the client as a download and when you hit the download button nothing happens.
Private Sub lkbDownloadPdfs_Click(sender As Object, e As System.EventArgs) Handles aDownloadPdfs.ServerClick
Try
Dim WSStockToolAuthTokenUrl As String = ConfigurationManager.AppSettings("WSStockToolAuthTokenUrl")
Dim auth As AuthenticationHeader = Utility.GetAuthenticationForStockToolToken()
Dim token As String = Utility.GetInitializationToken(WSStockToolAuthTokenUrl, auth.UserName, auth.password)
Response.Clear()
Response.ContentType = "application/zip"
Response.AppendHeader("Content-Disposition", "attachment; filename=files.zip")
If (token IsNot Nothing) Then
Dim result As String = PDFApiCallResult(token)
Dim pdfPathList As List(Of String) = Utility.GeneratePDFList(result)
If (pdfPathList.Count = 1) Then
Dim pdfPath As String = pdfPathList.ElementAt(0)
Dim strFile As String
Dim strmZipOutputStream = New ZipOutputStream(Response.OutputStream)
strmZipOutputStream.SetLevel(9)
Dim objCrc32 As New Crc32()
For Each strFile In pdfPathList
Dim Client As WebClient = New WebClient()
Dim strmFile As Stream = Client.OpenRead(strFile)
Dim reader As StreamReader = New StreamReader(strmFile)
Dim Content As String = reader.ReadToEnd()
Dim abyBuffer(Convert.ToInt32(Content.Length - 1)) As Byte
Dim sFile As String = Path.GetFileName(strFile)
Dim theEntry As ZipEntry = New ZipEntry(sFile)
theEntry.DateTime = DateTime.Now
theEntry.Size = Content.Length
strmFile.Close()
objCrc32.Reset()
objCrc32.Update(abyBuffer)
theEntry.Crc = objCrc32.Value
strmZipOutputStream.PutNextEntry(theEntry)
strmZipOutputStream.Write(abyBuffer, 0, abyBuffer.Length)
Next
strmZipOutputStream.Flush()
strmZipOutputStream.Finish()
strmZipOutputStream.Close()
Response.Flush()
Response.Close()
Response.SuppressContent = True
HttpContext.Current.ApplicationInstance.CompleteRequest()
Else
End If
End If
Catch ex As Exception
ExceptionManager.Publish(ex)
End Try
End Sub
Any help? (If you have working C# code I could try to convert it to vb.net too)
Update 1: This is the aspx where the link which does the callback resides:
<asp:UpdatePanel runat="server" ID="updImages" UpdateMode="Conditional">
...
DOWNLOAD PDFS
...
<asp:AsyncPostBackTrigger ControlID="lkbAddToWishlist" />
<asp:AsyncPostBackTrigger ControlID="ddlCustomizations" />
</asp:UpdatePanel>
I've read that maybe the response is not working at all because of the ajax way the update panel does the postback, but not sure about that and how to deal with that.

Related

VB.net Crystal report export to html and send as html mail body using outlook

I am trying to send contents of a crystal report as email body using outlook application.
Here is my code in VB.net
Imports outlook = Microsoft.Office.Interop.Outlook
Dim a As String = something.ConnectionString
Dim cryRpt As ReportDocument
Dim username As String = a.Split("=")(3).Split(";")(0) 'get username
Dim password As String = a.Split("=")(4).Split(";")(0) 'get password
cryRpt = New ReportDocument()
Dim Path As String = Application.StartupPath
Dim svPath As String = Application.StartupPath & "\PDF"
If Not Directory.Exists(svPath) Then
Directory.CreateDirectory(svPath)
End If
cryRpt.Load(Path & "\Reports\dr.rpt")
CrystalReportViewer1.ReportSource = cryRpt
cryRpt.SetDatabaseLogon(username, password)
CrystalReportViewer1.Refresh()
Dim myExportOptions As ExportOptions
myExportOptions = cryRpt.ExportOptions
myExportOptions.ExportDestinationType = ExportDestinationType.DiskFile
myExportOptions.ExportFormatType = ExportFormatType.HTML40 'i tried HTML32 also
Dim html40FormatOptions As HTMLFormatOptions = New HTMLFormatOptions()
html40FormatOptions.HTMLBaseFolderName = svPath
html40FormatOptions.HTMLFileName = "dr.htm"
html40FormatOptions.HTMLEnableSeparatedPages = False
html40FormatOptions.HTMLHasPageNavigator = False
html40FormatOptions.UsePageRange = False
myExportOptions.FormatOptions = html40FormatOptions
cryRpt.Export()
Try
Dim oApp As outlook.Application
oApp = New outlook.Application
Dim oMsg As outlook.MailItem
oMsg = oApp.CreateItem(outlook.OlItemType.olMailItem)
oMsg.Subject = txtSubject.Text
oMsg.BodyFormat = outlook.OlBodyFormat.olFormatHTML
oMsg.HTMLBody = ""
oMsg.HTMLBody = getFileAsString(svPath & "\PoPrt\QuotPrt.html")
oMsg.To = txtEmailId.Text
Dim ccArray As New List(Of String)({txtCC1.Text, txtCC2.Text, txtCC3.Text})
Dim cclis As String = String.Join(",", ccArray.Where(Function(ss) Not String.IsNullOrEmpty(ss)))
oMsg.CC = cclis
oMsg.Display(True)
Catch ex As Exception
MsgBox("Something went wrong", vbExclamation)
End Try
SvFormPanel3.Visible = False
the function
Private Function getFileAsString(ByVal file As String) As String
Dim reader As System.IO.FileStream
Try
reader = New System.IO.FileStream(file, IO.FileMode.Open)
Catch e As Exception
MsgBox("Something went wrong. " + e.Message, vbInformation)
End Try
Dim resultString As String = ""
Dim b(1024) As Byte
Dim temp As UTF8Encoding = New UTF8Encoding(True)
Do While reader.Read(b, 0, b.Length) > 0
resultString = resultString & temp.GetString(b)
Array.Clear(b, 0, b.Length)
Loop
reader.Close()
Return resultString
End Function
The report will get exported to the specified location as html. And when we manually open that html file it displays perfectly with border lines and all.
But when its getting added as html body of outlook application, the formatting will be gone, and looks scattered.
can anyone help
Did you try this?
Open outlook, go to, File>Options>Mail
go to section MessageFormat and untick "Reduce message size by removing format..."
I have solved the issue by exporting it into PDF and then convert to Image and embed in email body.

Background Program Not Looping

I have a program that runs in the background looping to check if a page on the site has been changed. It works once and shows the message box but if I change it again it won't do anything.
Imports System.Net
Imports System.String
Imports System.IO
Module Main
Sub Main()
While 1 = 1
Dim client As WebClient = New WebClient()
Dim reply As String = client.DownloadString("http://noahcristinotesting.dx.am/file.txt")
If reply.Contains("MsgBox") Then
Dim Array() As String = reply.Split(":")
MessageBox.Show(Array(2), Array(1))
Dim request As System.Net.FtpWebRequest = DirectCast(System.Net.WebRequest.Create("ftp://noahcristinotesting.dx.am/noahcristinotesting.dx.am/file.txt"), System.Net.FtpWebRequest)
request.Credentials = New System.Net.NetworkCredential("username", "password")
request.Method = System.Net.WebRequestMethods.Ftp.UploadFile
Dim path As String = "C:\test.txt"
Dim createText As String = "completed"
File.WriteAllText(path, createText)
Dim fileftp() As Byte = System.IO.File.ReadAllBytes("C:\test.txt")
Dim strz As System.IO.Stream = request.GetRequestStream()
strz.Write(fileftp, 0, fileftp.Length)
strz.Close()
strz.Dispose()
End If
End While
End Sub
End Module
Not sure at this moment what is causing it to crash when run outside of the IDE, but try trapping exceptions that are being thrown in the loop. I imagine there's an exception happening, cratering your app. The below catch block is by no means production ready, normally you want to catch specific exceptions in order to handle them effectively, but this is a cheap way to see if an exception is being thrown and what it is at runtime.
Sub Main()
Try
While 1 = 1
Dim client As WebClient = New WebClient()
Dim reply As String = client.DownloadString("http://noahcristinotesting.dx.am/file.txt")
If reply.Contains("MsgBox") Then
Dim Array() As String = reply.Split(":")
MessageBox.Show(Array(2), Array(1))
Dim request As System.Net.FtpWebRequest = DirectCast(System.Net.WebRequest.Create("ftp://noahcristinotesting.dx.am/noahcristinotesting.dx.am/file.txt"), System.Net.FtpWebRequest)
request.Credentials = New System.Net.NetworkCredential("username", "password")
request.Method = System.Net.WebRequestMethods.Ftp.UploadFile
Dim path As String = "C:\test.txt"
Dim createText As String = "completed"
File.WriteAllText(path, createText)
Dim fileftp() As Byte = System.IO.File.ReadAllBytes("C:\test.txt")
Dim strz As System.IO.Stream = request.GetRequestStream()
strz.Write(fileftp, 0, fileftp.Length)
strz.Close()
strz.Dispose()
End If
End While
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Alternatively, you could check your event viewer in windows to see if a .net application exception is being logged. Event Viewer > Windows Logs > Application

vb.net proper way to thread this application

My application is a web scraper (for the most part) that stores information in a database. I have 2 classes so far:
clsSpyder - This essentially rolls-up the scraper processes
clsDB - This does any database processes
My test program looks over all the URLs, scrapes, pushes into the database. It is pretty simple sequentially, but I would like to have say N number of threads running those processes (scrape and store). My sequential code is this:
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
'Grab List
Dim tDS As New DataSet
Dim tDB As New clsTermsDB
Dim tSpyder As New clsAGDSpyder
Dim sResult As New TermsRuns
'Grab a list of all URLS
tDS = tDB.GetTermsList(1)
Try
For Each Row As DataRow In tDS.Tables(0).Rows
rtbList.AppendText(Row("url_toBeCollected") & vbCrLf)
sResult = tSpyder.SpiderPage(Row("url_toBeCollected"))
'If nothing is found, do not store
If sResult.html <> "" And sResult.text <> "" Then
tDB.InsertScrape(Now(), sResult.html, sResult.text, Row("url_uid"), 1)
End If
Next
Exit Sub
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
With that in mind and noting that I am passing variables to the SpiderPage and InsertScrape methods.. How could I implement threading? It's gotta be simple, but I feel like I have been googling and trying things for days without success :(
*** ADDED: SpiderPage method:
Public Function SpiderPage(PageURL As String) As TermsRuns
Dim webget As New HtmlWeb
Dim node As HtmlNode
Dim doc As New HtmlDocument
Dim docNOHTML As HtmlDocument
Dim uri As New Uri(PageURL)
Dim wc As HttpWebRequest = DirectCast(WebRequest.Create(uri.AbsoluteUri), HttpWebRequest)
Dim wcStream As Stream
wc.AllowAutoRedirect = True
wc.MaximumAutomaticRedirections = 3
'Set Headers
wc.UserAgent = "Mozilla/5.0 (Macintosh; I; Intel Mac OS X 11_7_9; de-LI; rv:1.9b4) Gecko/2012010317 Firefox/10.0a4"
wc.Headers.Add("REMOTE_ADDR", "66.83.101.5")
wc.Headers.Add("HTTP_REFERER", "66.83.101.5")
'Set HTMLAgility Kit Useragent Spoofing (not needed, I don't think)
webget.UserAgent = "Mozilla/5.0 (Macintosh; I; Intel Mac OS X 11_7_9; de-LI; rv:1.9b4) Gecko/2012010317 Firefox/10.0a4"
'Certification STuff
wc.UseDefaultCredentials = True
wc.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials
ServicePointManager.ServerCertificateValidationCallback = AddressOf AcceptAllCertifications
'Create Cookie Jar
Dim CookieJar As New CookieContainer
wc.CookieContainer = CookieJar
'Keep Alive Settings
wc.KeepAlive = True
wc.Timeout = &H7530
'Read the web page
Dim wr As HttpWebResponse = Nothing
Try
wcStream = wc.GetResponse.GetResponseStream
doc.Load(wcStream)
'Remove HTML from the document
docNOHTML = RemoveUnWantedTags(doc)
'Grab only the content inside the <body> tag
node = docNOHTML.DocumentNode.SelectSingleNode("//body")
'Output
SpiderPage = New TermsRuns
SpiderPage.html = node.InnerHtml
SpiderPage.text = node.InnerText
Return SpiderPage
Catch ex As Exception
'Something goes here when scraping returns an error
SpiderPage = New TermsRuns
SpiderPage.html = ""
SpiderPage.text = ""
End Try
End Function
*** Added InsertScrape:
Public Function InsertScrape(scrape_ts As DateTime, scrape_html As String, scrape_text As String, url_id As Integer, tas_id As Integer) As Boolean
Dim myCommand As MySqlClient.MySqlCommand
Dim dt As New DataTable
'Create ds/dt for fill
Dim ds As New DataSet
Dim dtbl As New DataTable
Try
'Set Connection String
myConn.ConnectionString = myConnectionString
'Push Command to Client Object
myCommand = New MySqlClient.MySqlCommand
myCommand.Connection = myConn
myCommand.CommandText = "spInsertScrape"
myCommand.CommandType = CommandType.StoredProcedure
myCommand.Parameters.AddWithValue("#scrape_ts", scrape_ts)
myCommand.Parameters("#scrape_ts").Direction = ParameterDirection.Input
myCommand.Parameters.AddWithValue("#scrape_html", scrape_html)
myCommand.Parameters("#scrape_html").Direction = ParameterDirection.Input
myCommand.Parameters.AddWithValue("#scrape_text", scrape_text)
myCommand.Parameters("#scrape_text").Direction = ParameterDirection.Input
myCommand.Parameters.AddWithValue("#url_id", url_id)
myCommand.Parameters("#url_id").Direction = ParameterDirection.Input
myCommand.Parameters.AddWithValue("#tas_id", tas_id)
myCommand.Parameters("#tas_id").Direction = ParameterDirection.Input
'Open Connection
myConn.Open()
myCommand.ExecuteNonQuery()
'Close Connection
myConn.Close()
InsertScrape = True
Catch ex As Exception
'Put Message Here
InsertScrape = False
MessageBox.Show(ex.Message)
End Try
End Function
thanks in advance.

automatically download a report

This is the code that i have made but now working to save the report to the directory:
As you see i follow pretty much a lot of microsoft tutorials of how use this class of reporting service, but still dont get how get it working
'objetos de reporting
Dim rs As New reportingservice.ReportingService2010
Dim rsExec As New ReportExecution.ReportExecutionService
rs.Credentials = System.Net.CredentialCache.DefaultCredentials
'datos generales
Dim historyID As String = Nothing
Dim deviceInfo As String = Nothing
Dim format As String = "PDF"
Dim results As Byte()
Dim encoding As String = String.Empty
Dim mimeType As String = String.Empty
Dim extension As String = String.Empty
Dim warnings As ReportExecution.Warning() = Nothing
Dim streamIDs As String() = Nothing
Dim filename As String = "C:/Users/gdedieu/Desktop/reporte.pdf" ' Change to where you want to save
Dim _reportName As String = "per_anexo_1"
Dim _historyID As String = Nothing
Dim _forRendering As Boolean = False
Dim _values As ReportExecution.ParameterValue() = Nothing
Dim _credentials As reportingservice.DataSourceCredentials() = Nothing
Dim ei As ReportExecution.ExecutionInfo = rsExec.LoadReport(_reportName, historyID)
'definimos el parĂ¡metro
_values(0).Name = "an1_id"
_values(0).Value = 1
rsExec.SetExecutionParameters(_values, "en-us")
results = rsExec.Render(format, deviceInfo, extension, mimeType, encoding, warnings, streamIDs)
Dim stream As New System.IO.FileStream(filename, IO.FileMode.OpenOrCreate)
stream.Write(results, 0, results.Length)
stream.Close()
Try setting up a subscription via the Report Manager and specifying the Report Delivery Options value for 'Delivered By:' as 'Report Server File Share'.
This lets you specify a path for a report file to be written to - you will need to ensure that the Reporting Services server has write access to the destination.

VB.NET Show message after FTP upload complete

I'm trying to create a uploader to FTP, although the file uploads perfectly, I am just wondering how I would be able to show a message after the ftp process has complete.
Close()
Dim s As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
Dim r As New Random
Dim sb As New StringBuilder
For i As Integer = 1 To 8
Dim idx As Integer = r.Next(0, 35)
sb.Append(s.Substring(idx, 1))
Next
Using ms As New System.IO.MemoryStream
sc.CaptureDeskTopRectangle(Me.boundsRect).Save(ms, System.Drawing.Imaging.ImageFormat.Png)
Using wc As New System.Net.WebClient
wc.UploadData("ftp://MYUSERNAME:MYPASSWORD#MYSITE.COM/" + sb.ToString() + ".png", ms.ToArray())
End Using
End Using
How would I manage this?
Edit: Also as you can see I use a random string.. although If I use sb.ToString() twice will it give me the exact same result for both? If not how can I manage this??
You need to declare the Random as Static. The UploadData has a UploadDataCompleted event you can listen for.
Dim s As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
Static r As New Random
Dim sb As New StringBuilder
For i As Integer = 1 To 8
Dim idx As Integer = r.Next(0, 35)
sb.Append(s.Substring(idx, 1))
Next
Using ms As New System.IO.MemoryStream
sc.CaptureDeskTopRectangle(Me.boundsRect).Save(ms, System.Drawing.Imaging.ImageFormat.Png)
Using wc As New System.Net.WebClient
AddHandler wc.UploadDataCompleted, AddressOf UploadCompleted
wc.UploadData("ftp://MYUSERNAME:MYPASSWORD#MYSITE.COM/" + sb.ToString() + ".png", ms.ToArray())
End Using
End Using
Private Sub UploadCompleted(sender As Object, e As Net.UploadDataCompletedEventArgs)
'do completed work here
End Sub
I don't think you can use the UploadData like that. Here is a Link for an example of ftp uploading.
Public Shared Sub Main()
' Get the object used to communicate with the server.
Dim request As FtpWebRequest = DirectCast(WebRequest.Create("ftp://www.contoso.com/test.htm"), FtpWebRequest)
request.Method = WebRequestMethods.Ftp.UploadFile
' This example assumes the FTP site uses anonymous logon.
request.Credentials = New NetworkCredential("anonymous", "janeDoe#contoso.com")
' Copy the contents of the file to the request stream.
Dim sourceStream As New StreamReader("testfile.txt")
Dim fileContents As Byte() = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd())
sourceStream.Close()
request.ContentLength = fileContents.Length
Dim requestStream As Stream = request.GetRequestStream()
requestStream.Write(fileContents, 0, fileContents.Length)
requestStream.Close()
Dim response As FtpWebResponse = DirectCast(request.GetResponse(), FtpWebResponse)
Console.WriteLine("Upload File Complete, status {0}", response.StatusDescription)
response.Close()
End Sub