Visual Basic Download Not Doing Anything On Completion - asp.net

My other issue was with a bigger file made dynamically but now I'm just doing a small, already existing text file to try and get this concept working at least.
I'm attempting to download a file when the user clicks on the button but after the Response lines run nothing seems to download nor does the browser recognize a possible download. I've stepped through it as well as it just goes through every line but the front end no download file begins or prompted for. The file is currently in the bin file of the project and I've also tried just in my own local downloads file. Just contains "hello" nothing major.
The asp:
<asp:button id = "Button1" Class="button" text = "TEST" runat = "server" />
And the vb
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim fileToDownload = Server.MapPath("~/bin/test.txt")
Response.ContentType = "text/plain"
Response.AppendHeader("Content-Disposition", "attachment; filename=test.txt")
Response.TransmitFile(fileToDownload)
Response.Flush()
Response.End()
I've tried the response lines in different orders, as well as just using flush or just end. This is just a tempt file of course as the bigger scheme is to dynamically create and excel file and download that to the user.

edit: sry, i just tried your code as-is and it worked on my machine. i'm using firefox. i've seen some long articles about dealing with internet explorer. any chance you're using that?
original post:
can a file be downloaded from bin? just a thought.
also, try removing Response.Flush() and see if that helps. i think Response.End takes care of that - when everything is actually done.

Related

DotNetZip download works in one site, not another

EDIT - RESOLVED: the difference was that in the "main" case the download was initiated via a callback cycle, and in the "test" case it was initiated through a server side button click function. My guess is that the download request and the callback cycle interfered with each other, both stopping the download and causing the page to become inactive (as described below). When I rewired the download on the main page to start with a submit instead of a callback, it did initiate the download.
This is in VS2013 Ultimate, Win7Pro, VB.Net, websites (not projects),IISExpress.
I built a test site to develop functionality for creating OpenXML PPTX and XLSX memorystreams and zipping and downloading them using DotNetZip. Got it to work fine. I then merged all that code into my "main" site. Both sites are on the same machine; I can run the test site and the main site at the same time. The main site processing is somewhat more complicated, but only in terms of accessing and downloading more files.
However, the Zip and Download function (below) works fine in the test site, but the exact same code doesn't work in the main site (with or without the test site up and running).
There's an error trap (see below) around the Zip.Save function where the download occurs but no error shows up.
Same overall behavior in Chrome, Firefox and IE11.
One peculiarity that might be a clue is that when the main site download fails, the server side functionality "goes dead". Local JS functions work, but the app doesn't respond to callbacks. When I do an F5 on the browser it works again.
I did a refresh on the DotNetZip package in the main site. The Zip object appears to be working properly, because it generates an error on duplicate file names.
I thought it might be the download function as written, however, it works in the test site. Also, another piece of the main site does a non-zipped download of a memory stream (included as the second code block below) and that works fine.
I thought it might be the data. So I kludged the main site to access, convert to memorystream and download the same file that the is accessed and downloaded in the test site. Still the main site download doesn't work.
When I compare the watch values on the Zip object in the two sites, they look identical. The length of the wrkFS.ContentStream is identical in both cases. The file names are different, however, they are:
Test_2EFVG1THK5.xlsx (main)
6-18_12-46-28_0.xlsx (test)
which are both legal file names.
EDIT: I saved the zip file to disk from the main program, instead of trying to download it, using this:
wrkFilePath = "D:\filepath\test.zip"
wrkZip.Save(wrkFilePath)
And it worked fine. So that possibly isolates the problem to this statement
wrkZip.Save(context.Response.OutputStream)
EDIT: Base on help I received here:
Convert DotNetZip ZipFile to byte array
I used this construct:
Dim ms as New MemoryStream
wrkZip.Save(ms)
wrkBytes = ms.ToArray()
context.Response.BinaryWrite(wrkByteAr)
to get around the ZipFile.Save(to context), and that didn't work either; no download, no error message, and page goes dead. However, at least I can now assume it's not a problem with the ZipFile.Save.
At this point I'm out of ways to diagnose the problem.
Any suggestions would be appreciated.
Here is the code that works in the test site but not in the main site.
Public Sub ZipAndDownloadMemoryStreams(ByVal context As HttpContext) _
Implements IHttpHandler.ProcessRequest
Dim rtn As String = ""
Try
Dim wrkAr As ArrayList
wrkAr = SC.ContentArrayForDownLoad
If wrkAr.Count = 0 Then
Dim wrkStop As Integer = 0
Exit Sub
End If
Dim wrkFS As ZipDownloadContentPair
Using wrkZip As New ZipFile
'----- create zip, add memory stream----------
For n As Integer = 0 To wrkAr.Count - 1
wrkFS = wrkAr(n)
wrkZip.AddEntry(wrkFS.FileName, wrkFS.ContentStream)
Next
context.Response.Clear()
context.Response.ContentType = "application/force-download"
context.Response.AddHeader( _
"content-disposition", _
"attachment; filename=" & "_XYZ_Export.zip")
'---- save context (initiate download)-----
wrkZip.Save(context.Response.OutputStream)
wrkZip.Dispose()
End Using
Catch ex As Exception
Dim exmsg As String = ex.Message
Dim wrkStop As String = ""
End Try
End Sub
Below is the non-zip download function that works fine in the main site.
It might be possible to convert the Zip content to a byte array and try the download that way, however, I'm not sure how that would work.
(SEE EDIT NOTE ABOVE --- I implemented a version of the below, i.e. try to download byte array instead of directly ZipFile.Save(), however, it didn't help; still doesn't download, and still doesn't give any error message)
Public Sub DownloadEncryptedMemoryStream(ByVal context As HttpContext) _
Implements IHttpHandler.ProcessRequest
Dim wrkMemoryStream As New System.IO.MemoryStream()
wrkMemoryStream = SC.ContentForDownload
Dim wrkFileName As String = SC.ExportEncryptedFileName
wrkMemoryStream.Position = 0
Dim wrkBytesInStream As Byte() = New Byte(wrkMemoryStream.Length - 1) {}
wrkMemoryStream.Read(wrkBytesInStream, 0, CInt(wrkMemoryStream.Length))
Dim wrkStr As String = ""
wrkStr = Encoding.UTF8.GetString(wrkMemoryStream.ToArray())
wrkMemoryStream.Close()
context.Response.Clear()
context.Response.ContentType = "application/force-download"
context.Response.AddHeader("content-disposition", "attachment; filename=" & wrkFileName)
context.Response.BinaryWrite(wrkBytesInStream)
wrkBytesInStream = Nothing
context.Response.End()
(Per the note now at the top of the question): The difference was that in the "main" case the download was initiated via a callback cycle, and in the "test" case it was initiated through a server side button click function. My guess is that the download request and the callback cycle interfered with each other, both stopping the download and causing the page to become inactive (as described below). When I rewired the download on the main page to start with a submit instead of a callback, it did initiate the download.

Opening a web page as an Excel file, but with .xlsx files

Okay, this might be a bit unusual. If there are better ways to do this (that are just as easy, I'm open to ideas). I found a while ago that I could open a web page consisting of a Gridview or a table, with titles, etc. as an excel file and it worked great! It formatted the Excel file with colors and alignment similar to the html from the page. With later versions of excel, though, it gives me a warning that the format time isn't valid before opening it, though it still seemed to work. So I tried changing the content type to a more current version of excel, but then I don't get anything at all. Here's what I have been doing (below).
Does anyone know how to change it so that I can open the page in a current version of Excel without getting the warning?
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Response.AppendHeader("Content-disposition", "attachment; filename=Filename.xls")
Response.ContentType = "application/vnd.ms-excel"
End Sub
You are not creating an Excel file.
You are creating a HTML file with a .xls file extension. That's the wrong extension for a HTML file, and that's why Excel gives you a warning. The correct extension would be .html or .htm. Unfortunately, .html files don't automatically open in Excel, so changing the extension would require your users to manually open the file in Excel instead of just double-clicking it.
I'm afraid there's no easy way to solve this. We had the same problem, and we solved it by creating a real Excel file. There are lots of Excel libraries for .NET available. We used SpreadsheetLight, because it easily allows you to copy a DataTable to an Excel file and send that file to the web client.

Read source of popup windows opened with javacript:void()?

I am going to do my best to ask this question as clearly as possible. Is it possible to write some asp.net code that can go through and read the source of pop up windows that are normally opened by clicking a javascript:void() link. Basically i want to read the source of said popups, extract specific links and then render those links in a web page. What i am trying to achieve is a way to make it easy to download the videos of the Senate floor - their videos open in a new popup that uses silverlight. The mp4 file location is in the source so i want to read that url. I did something similar using the code below. The difference was that the mp4 links were in main page. The code read the source and then outputted the video links so i could just right click and do a save as. This was for the videos at the German security conference. Apologies if this is not seen as a constructive question and ends up being closed.
Protected Sub btnClick_Click(sender As Object, e As EventArgs) Handles btnClick.Click
Dim r As New Regex("\bhttps?://\S+\.(?:jpg|png|gif|mp3|mp4|3gp)\b", RegexOptions.IgnoreCase)
Dim c As New WebClient
Dim s As String = c.DownloadString(txtUrl.Text)
Dim sb As New StringBuilder
For Each m As Match In r.Matches(s)
sb.Append("" & m.Value & "<br />")
divLinks.InnerHtml = sb.ToString
Next
End Sub

Trying to retrieve spreadsheet from asp site without any prompts

I have a company site that publishes large reports which I pull down and split up into what I need. I can get the webpage open and get the link to the spreadsheet I need opened, but then I get one IE pop-up for open/save/cancel and, when I click to open the spreadsheet, I get a second pop-up (this one from Excel) saying that the spreadsheet is in a different format than specified by the extension." I have no idea how, if possible, to get the first pop-up to away; the only way I know to normally prevent pop-ups with excel is with DisplayAlerts=False, but adding that doesn't seem to have any effect. The code for the start of this automation project follows:
[EDIT] I have edited and replaced the original coding to reflect the most recent attempt at this. I have managed to get past the first file download pop-up (though with the use of sendkeys) and am now working on getting the second pop-up taken care of (which I suppose is a matter of shifting focus back to excel). Any suggestions on replacing the sendkeys portion are definitely welcomed, as well as advice for returning focus to excel so that I can use excel to control the second pop-up (if that's the best way to do it). The updated code follows:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Sub Automation()
Dim IeApp As Object
Dim IeDoc As Object
Dim URL, URL2 As String
Application.DisplayAlerts = False
URL = "https://companysite.com/directorypage/default.aspx"
URL2 = "https://companysite.com/directorypage/Reports/MyReport.aspx?Format=Excel"
Set IeApp = CreateObject("InternetExplorer.Application")
IeApp.Visible = True
IeApp.Navigate URL
While IeApp.Busy Or IeApp.ReadyState <> 4: DoEvents: Wend
IeApp.Document.All.Item("MainContent_btnAuthenticate").Click
While IeApp.Busy Or IeApp.ReadyState <> 4: DoEvents: Wend
Set IeApp = CreateObject("InternetExplorer.Application")
IeApp.Visible = False
IeApp.Navigate URL2
Do Until thewindow <> 0 'wait for the "File Download" popup window to appear
thewindow = FindWindow(vbNullString, "File Download")
Loop
SendKeys "{LEFT}"
Application.Wait Now + TimeValue("00:00:01")
SendKeys "{LEFT}"
Application.Wait Now + TimeValue("00:00:01")
SendKeys "{ENTER}"
End Sub
You're not going to be able to suppress that message in your code, it's a setting on the user's workstation to prevent harm from malicious files.
The user would have to either edit their Windows registry or have it controlled via a group policy setting. http://support.microsoft.com/kb/948615
I ran across this same issue with Excel documents generated on on the server. The only workaround I made was to create files using the Open XML SDK.
EDIT: I read your question again and noticed it's more focused on the first pop-up, and JMax linked answer (How to disable file download popup in Internet Explorer?) should fix that.
Jon, my two cents on this.
If you have administrative access to your pc then what JMax suggested will sort it out. I would discourage editing the registry if you are an administrator until and unless you know what you are doing.
If it is say an office pc then editing the registry is not even an option. You will have to contact the IT dept. They can either login to your pc as an administrator and then turn the option off for you or they can tweak the GP as zeroef suggested. My best guess is that if it is an office pc then they will login as an administrator and make the changes for you individually instead of making the change in the GP (unless you are the only member of that group). In a corporate environment it is really difficult to get that pulled off via GP as it affects lot of users. There is also a possibility that your request might not be agreed upon if it is an Office pc.
BTW, from what I see, your question has nothing to do with it being an Excel problem :)
HTH
Sid
You could just download the file directly...
Private Declare Function URLDownloadToFile Lib "urlmon" Alias _
"URLDownloadToFileA" (ByVal pCaller As Long, _
ByVal szURL As String, ByVal _
szFileName As String, ByVal dwReserved As Long, _
ByVal lpfnCB As Long) As Long
Sub DownloadFile(sURL, sSaveAs)
Dim rv As Long
rv = URLDownloadToFile(0, sURL, sSaveAs, 0, 0)
If rv <> 0 Then
MsgBox "Error with download!"
End If
End Sub
Don't know if the https will be an issue here.
Another thing to try is just:
Workbooks.Open "https://companysite.com/directorypage/Reports/MyReport.aspx?Format=Excel"

Creating a dynamic graphic in asp.net

I am busy creating a control in asp.net. The control consists of some text and an image. The image will be used to display a graph. The control gets the data for the graph by reading it from a database. It seems I have two options to display the graph in the image box. First, I can create a jpg from the data and save the file on the server. I can then load this file into the image box. I think this would cause a problem if various users try to access the site at the same time, so I don't think it is a good option. The other options is to create a file called output, that outputs the graph like this: objBitmap.Save(Response.OutputStream, ImageFormat.Gif)
I can then display the image like this in my control: Image1.ImageUrl = "output.aspx"
The problem that I am facing is how do I get the data from my control to the output page? As far as I know it is too much data to pass as a parameter. If there is another better method of doing it, please let me know
Thanks
You can write the image content to the response of output.aspx. Something like this (taken from one of my existing GetImage pages:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim strFilename As String
strFilename = Request.QueryString("filename")
Dim strPath As String = AppSettings("ProxyImageSavePath") & strFilename
Response.Clear()
Response.ContentType = "image/jpeg"
If Not IO.File.Exists(strPath) Then
'erm
Response.Write("file not found")
Else
Response.WriteFile(strPath)
End If
Response.End()
End Sub
Edit: I've just realised this may not be the solution you're looking for; Your webserver should be able to cache this though.
You need handlers. See in this article, Protecting Your Images, section "Creating the ImageHandler HTTP Handler", you'll find the code how to write the handler, so it outputs an image. You don't need all, it's only an example.
You also need to register the handler in the web.config.
To reference it Image1.ImageUrl = "handler.ashx?graphdata=xxxx". Use QueryString to get the data source to generate the graph.

Resources