Stuck on trying to download a file over https, works fine across http but get the message in firefox - 'FILENAME could not be saved because the source file could not be read' and 'Failed - Network Error' in Chrome.
Web application sits behind Cisco firewall in which i have opened all the ports and still no joy. Flomoxed.
Dim file As System.IO.FileInfo = New System.IO.FileInfo(FullFilePath) '-- if the file exists on the server
If file.Exists Then 'set appropriate headers
Response.ClearContent()
Response.ClearHeaders()
Dim iStream As System.IO.Stream = Nothing
' Buffer to read 10K bytes in chunk:
Dim buffer(10000) As Byte
' Length of the file:
Dim length As Integer
' Total bytes to read:
Dim dataToRead As Long
Try
' Open the file.
iStream = New System.IO.FileStream(FullFilePath, System.IO.FileMode.Open,
IO.FileAccess.Read, IO.FileShare.Read)
' Total bytes to read:
dataToRead = iStream.Length
'Response.ContentType = "application/octet-stream"
Response.ContentType = "application/pdf"
'Response.ContentType = WebApp.Common.Functions.ReturnContentType(file.Extension.ToLower())
Response.AddHeader("Content-Disposition", "attachment; filename=""" & file.Name & """")
' Read the bytes.
While dataToRead > 0
' Verify that the client is connected.
If Response.IsClientConnected Then
' Read the data in buffer
length = iStream.Read(buffer, 0, 10000)
' Write the data to the current output stream.
Response.OutputStream.Write(buffer, 0, length)
' Flush the data to the HTML output.
Response.Flush()
ReDim buffer(10000) ' Clear the buffer
dataToRead = dataToRead - length
Else
'prevent infinite loop if user disconnects
dataToRead = -1
End If
End While
Catch ex As Exception
' Trap the error, if any.
Response.Write("Error : " & ex.Message)
Finally
If iStream IsNot Nothing Then
' Close the file.
iStream.Close()
End If
Response.Close()
End Try
Response.End() 'if file does not exist
Else
Response.Write("This file does not exist.")
End If 'nothing in the URL as HTTP GET
Related
I have been breaking my head for the last two days and can't get this to work. I have a report, which I am exporting to Excel and saving on the server file directory. That part works perfectly, I can see the file, and open it, all good. The issue relies on when I try to send it to the browser for download from the server. It does not download anything, I do see the Response Header with all the info on the browser but nothing happens.
Here's one of my many tries
Private Sub dxgvPOAll_ToolbarItemClick(source As Object, e As ASPxGridViewToolbarItemClickEventArgs) Handles dxgvPOAll.ToolbarItemClick
Select Case e.Item.Name
Case "ExportAll"
Using report As DevExpress.XtraReports.UI.XtraReport = New POs_Dashboard_Report()
Using ms As New System.IO.MemoryStream()
report.Name = "Backorder Tickets"
report.ExportOptions.PrintPreview.SaveMode = DevExpress.XtraPrinting.SaveMode.UsingSaveFileDialog
Dim xlsxExportOptions As New DevExpress.XtraPrinting.XlsxExportOptions() With {.ExportMode = DevExpress.XtraPrinting.XlsxExportMode.SingleFile, .ShowGridLines = True, .FitToPrintedPageHeight = True}
Dim folderPath As String = "~/Account/TemporaryFiles/" & Utilities.RetrieveEmployeeNumber() & "/" & Guid.NewGuid.ToString & "/"
Dim serverPath As String = Server.MapPath(folderPath)
Dim xlsxExportFilePath As String = serverPath & report.Name & ".xlsx"
Dim folderInf As New DirectoryInfo(serverPath)
If Not folderInf.Exists Then folderInf.Create()
report.ExportToXlsx(xlsxExportFilePath, xlsxExportOptions)
Try
Dim objRequest As FileWebRequest = CType(WebRequest.Create(xlsxExportFilePath), FileWebRequest)
Dim objResponse As FileWebResponse = CType(objRequest.GetResponse(), FileWebResponse)
Dim bufferSize As Integer = 1
Response.Clear()
Response.ClearHeaders()
Response.ClearContent()
Response.AppendHeader("Content-Disposition:", "attachment; filename=" & xlsxExportFilePath)
Response.AppendHeader("Content-Length", objResponse.ContentLength.ToString())
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
Dim byteBuffer As Byte() = New Byte(bufferSize + 1 - 1) {}
Dim memStrm As MemoryStream = New MemoryStream(byteBuffer, True)
Dim strm As Stream = objRequest.GetResponse().GetResponseStream()
Dim bytes As Byte() = New Byte(bufferSize + 1 - 1) {}
While strm.Read(byteBuffer, 0, byteBuffer.Length) > 0
Response.BinaryWrite(memStrm.ToArray())
Response.Flush()
End While
HttpContext.Current.Response.Flush()
HttpContext.Current.Response.SuppressContent = True
HttpContext.Current.ApplicationInstance.CompleteRequest()
Catch e1 As ThreadAbortException
Catch ex As Exception
End Try
End Using
End Using
End Select
End Sub
Here's what I see on the browser's Response-Header:
I'm trying to download a file with size greater than 50mb in an asp.net page. But it fails on our production server. It works on development and QA servers. I'm using the following code.
Response.Clear()
oBinaryReader = New System.IO.BinaryReader(System.IO.File.OpenRead(sDocPath))
lFileSize = Microsoft.VisualBasic.FileLen(sDocPath)
Response.AddHeader("Content-Disposition", "attachment;filename=" & sDownloadFileName)
Response.ContentType = "application/unknown"
Response.BinaryWrite(oBinaryReader.ReadBytes(lFileSize))
Response.Flush()
HttpContext.Current.ApplicationInstance.CompleteRequest()
Response.End()
The error I'm getting from the server is as below.
Page_Load System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.IO.BinaryReader.ReadBytes(Int32 count)
at ExportDoc.Page_Load(Object sender, EventArgs e) in c:\sitename\ExportDoc.aspx.vb:line 87 Server Name
What is wrong with the code?
OutOfMemoryException commonly thrown when there is no available memory to perform such operation when handling both managed/unmanaged resources. Therefore, you need to use Using...End Using block wrapping around BinaryReader to guarantee immediate disposal of unmanaged resources after usage with IDisposable interface:
Response.Clear()
Using oBinaryReader As BinaryReader = New BinaryReader(File.OpenRead(sDocPath))
lFileSize = FileLen(sDocPath)
Response.AddHeader("Content-Disposition", "attachment;filename=" & sDownloadFileName)
Response.ContentType = "application/unknown"
Response.BinaryWrite(oBinaryReader.ReadBytes(lFileSize))
Response.Flush()
HttpContext.Current.ApplicationInstance.CompleteRequest()
Response.End()
End Using
Another common usage of BinaryReader is using FileStream and a byte buffer to control file reading mechanism:
Using FStream As FileStream = New FileStream(File.OpenRead(sDocPath))
lFileSize = CType(FStream.Length, Integer)
Dim Buffer() As Byte
Using oBinaryReader As BinaryReader = New BinaryReader(FStream)
Buffer = oBinaryReader.ReadBytes(lFileSize)
End Using
Response.Clear()
Response.AddHeader("Content-Disposition", "attachment;filename=" & sDownloadFileName)
Response.ContentType = "application/unknown"
Response.BinaryWrite(Buffer)
Response.Flush()
HttpContext.Current.ApplicationInstance.CompleteRequest()
Response.End()
End Using
References:
VB.NET Using Statement (MSDN)
BinaryReader Class (MSDN)
I tried the below code and it resolved my issue, found the code idea from MSDN website.
Using iStream As System.IO.Stream = New System.IO.FileStream(sDocPath, System.IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
dataToRead = iStream.Length
Response.ContentType = "application/octet-stream"
Response.AddHeader("Content-Disposition", "attachment; filename=" & filename)
While dataToRead > 0
If Response.IsClientConnected Then
length = iStream.Read(buffer, 0, bufferSize)
Response.OutputStream.Write(buffer, 0, length)
Response.Flush()
ReDim buffer(bufferSize)
dataToRead = dataToRead - length
Else
dataToRead = -1
End If
End While
HttpContext.Current.ApplicationInstance.CompleteRequest()
End Using
I have a website written in Classic ASP
One page creates a .CSV file from a SQL database and stores it in the root directory along with a "Click Here" link to download it to the users PC
It has been working fine for many years and is still working fine when downloading small files, but now it comes up with a "THIS PAGE CAN'T BE DISPLAYED" error when downloading a .csv file (in this example) of some 785 records
The code is pretty short as below with the one Private Sub that does the download
<%#Language="VBScript"%>
<%Reponse.Buffer = True%>
<%
On Error Resume Next
Dim strPath
strPath = CStr(Request.QueryString("File"))
'-- do some basic error checking for the QueryString
If strPath = "" Then
Response.Clear
Response.Write("No file specified.")
Response.End
ElseIf InStr(strPath, "..") > 0 Then
Response.Clear
Response.Write("Illegal folder location.")
Response.End
ElseIf Len(strPath) > 1024 Then
Response.Clear
Response.Write("Folder path too long.")
Response.End
Else
Call DownloadFile(strPath)
End If
Private Sub DownloadFile(file)
'--declare variables
Dim strAbsFile
Dim strFileExtension
Dim objFSO
Dim objFile
Dim objStream
'-- set absolute file location
strAbsFile = Server.MapPath(file)
'-- create FSO object to check if file exists and get properties
Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
'-- check to see if the file exists
If objFSO.FileExists(strAbsFile) Then
Set objFile = objFSO.GetFile(strAbsFile)
'-- first clear the response, and then set the appropriate headers
Response.Clear
'-- the filename you give it will be the one that is shown
' to the users by default when they save
Response.AddHeader "Content-Disposition", "attachment; filename=" & objFile.Name
Response.AddHeader "Content-Length", objFile.Size
Response.ContentType = "application/octet-stream"
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Open
'-- set as binary
objStream.Type = 1
Response.CharSet = "UTF-8"
'-- load into the stream the file
objStream.LoadFromFile(strAbsFile)
'-- send the stream in the response
Response.BinaryWrite(objStream.Read)
objStream.Close
Set objStream = Nothing
Set objFile = Nothing
Else 'objFSO.FileExists(strAbsFile)
Response.Clear
Response.Write("No such file exists.")
End If
Set objFSO = Nothing
End Sub
%>
So something has changed in recent months
Ay advice much appreciated
Thanks in advance
Your IIS version and configuration might be needed to help but I know IIS6 introduced a 4MB limit to BinaryWrite. Try sending your file in chunks instead.
<% Response.Buffer = False %>
...
With Server.CreateObject("ADODB.Stream")
.Open
.Type = 1
.LoadFromFile strPath
' Send 256K chunks...
Const intChunkSize = 262144
Do While Response.IsClientConnected And (.Position < .Size)
Response.BinaryWrite .Read(intChunkSize)
Loop
.Close
End With
It's been a while since I've been here. I've been working on an ASP project where the attachment is stored to DB. I'm trying to get the bytes stored in the table to a file.
I was able to make the file, however, I couldn't get the bytes from the table.
This is the code that enters the file to the table:
'Saves the upload file data to database for the using Request_ID after the request has been created
strFileName = FileUploadReqDtl.FileName
strFileExt = strFileName.Substring(strFileName.IndexOf(".") + 1)
intFileSize = FileUploadReqDtl.PostedFile.ContentLength()
Dim theDataSize As Byte() = New Byte(FileUploadReqDtl.PostedFile.ContentLength - 1) {}
Dim uploadedFile As HttpPostedFile = FileUploadReqDtl.PostedFile
Dim theData = uploadedFile.InputStream.Read(theDataSize, 0, CInt(FileUploadReqDtl.PostedFile.ContentLength))
I was able to create a link on a page that goes to another ASP page and tries to make the file downloadable. I know that the SQL is working properly to get the records from the table, however, I'm not able to get the bytes properly:
If (dr.HasRows = True) Then
While dr.Read()
' Casting the value returned by the datareader to the byte[] data type.
result = CType(dr.GetValue(0), Byte())
strFileName = dr.GetString(1)
Debug.Write("strFileName: " & strFileName & vbCrLf)
End While
End If
dr.Close()
cnToDb.Close()
ShowFile(strFileName, result, MimeType)
Catch ex As Exception
MsgBox("Uh oh, I couldn't get the attachment!")
Debug.Write("Uh oh, I couldn't get the attachment!")
Debug.Write(ex.Message & " - " & ex.StackTrace & vbCrLf & vbCrLf)
result = Nothing
End Try
This is the ShowFile function which finally "creates the file" with the bytes from the database:
Dim fileData() As Byte
fileData = byteFileData
Response.Clear()
Response.AddHeader("Content-Disposition", "attachment; filename=" + strFileName)
Response.ContentType = MimeType
Response.BinaryWrite(fileData)
Response.End()
Response.Flush()
The exception I'm hitting that I'm having issues with is:
SQL: SELECT Data, FileName FROM tblFileUploadData WHERE Report_ID =
116
strFileName: TheAwesomeAttachment.txt A first chance exception of type
'System.Threading.ThreadAbortException' occurred in mscorlib.dll Uh
oh, I couldn't get the attachment!Thread was being aborted. - at
System.Threading.Thread.AbortInternal() at
System.Threading.Thread.Abort(Object stateInfo) at
System.Web.HttpResponse.End() at
WebApplication3.WebForm2.ShowFile(String strFileName, Byte[]
byteFileData, String MimeType) in C:\Users\Mike\documents\visual
studio
2010\Projects\WebApplication3\WebApplication3\Attachment.aspx.vb:line
81 at WebApplication3.WebForm2.getAttachment(Int32 RequestID,
String MimeType) in C:\Users\Mike\documents\visual studio
2010\Projects\WebApplication3\WebApplication3\Attachment.aspx.vb:line
56
A first chance exception of type
'System.Threading.ThreadAbortException' occurred in
WebApplication3.DLL An exception of type
'System.Threading.ThreadAbortException' occurred in
WebApplication3.DLL but was not handled in user code The thread '<No
Name>' (0x728) has exited with code 0 (0x0). The program '[13512]
WebDev.WebServer40.EXE: Managed (v4.0.30319)' has exited with code 0
(0x0). The program '[13512] WebDev.WebServer40.EXE: Program Trace' has
exited with code 0 (0x0).
Take a look at:
http://support.microsoft.com/kb/312629
"For Response.End, call the HttpContext.Current.ApplicationInstance.CompleteRequest method instead of Response.End to bypass the code execution to the Application_EndRequest event"
I like to create an .ashx file for this type of situation. You can link to it and it will download the file without showing a page.
Public Class DownloadFile
Implements System.Web.IHttpHandler
Public Sub ProcessRequest(context As HttpContext) Implements IHttpHandler.ProcessRequest
Try
Dim id As String = context.Request.QueryString("id")
Dim filename As String = ""
Dim output As Byte()
filename = ServiceHelper.GetFilenameByID(id)
output = ServiceHelper.GetFileBytesByID(id)
Dim ext As String = System.IO.Path.GetExtension(filename)
Dim contenttype As String
'clear the current output content from the buffer
context.Response.Clear()
'add the header that specifies the default filename for the
'Download/SaveAs dialog
context.Response.AddHeader("Content-Disposition", "attachment; filename=" & filename)
'add the header that specifies the file size, so that the browser
'can show the download progress
context.Response.AddHeader("Content-Length", output.Length.ToString())
'specify that the response is a stream that cannot be read by the
'client and must be downloaded
'Response.ContentType = "application/octet-stream"
context.Response.Buffer = True
Select Case ext
Case ".doc"
contenttype = "msword"
Case ".pdf"
contenttype = "pdf"
Case ".xls"
contenttype = "x-excel"
Case ".ppt"
contenttype = "ms-powerpoint"
Case Else
contenttype = "octet-stream"
End Select
context.Response.ContentType = "application/" & contenttype
context.Response.BinaryWrite(output)
'http://support.microsoft.com/kb/312629
'context.Response.End()
context.ApplicationInstance.CompleteRequest()
Catch
End Try
End Sub
Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class
I am creating a ASP.NET (VB.NET) application that must retrieve a known remote file and return it to the visitor through their browser. I am attempting to use the sample from Microsoft located here: http://support.microsoft.com/?kbid=812406 and running into an error 'This stream does not support seek operations'. I'm not sure how to proceed.
Here is the code with the error line marked.
Dim ftpWebReq As Net.FtpWebRequest = CType(Net.WebRequest.Create(path), Net.FtpWebRequest)
ftpWebReq.Method = Net.WebRequestMethods.Ftp.DownloadFile
ftpWebReq.KeepAlive = False
ftpWebReq.UsePassive = False
ftpWebReq.Credentials = New Net.NetworkCredential(System.Web.Configuration.WebConfigurationManager.AppSettings("FtpId"), System.Web.Configuration.WebConfigurationManager.AppSettings("FtpPwd"))
Dim ftpWebResp As Net.FtpWebResponse = CType(ftpWebReq.GetResponse(), Net.FtpWebResponse)
Dim streamer As Stream = ftpWebResp.GetResponseStream()
Dim buffer(10000) As Byte ' Buffer to read 10K bytes in chunk:
Dim length As Integer ' Length of the file:
Dim dataToRead As Long ' Total bytes to read:
dataToRead = streamer.Length ' *** This is the error line ***
Response.ContentType = "application/octet-stream"
Response.AddHeader("Content-Disposition", "attachment; filename=foo.txt")
While dataToRead > 0 ' Read the bytes.
If Response.IsClientConnected Then ' Verify that the client is connected.
length = streamer.Read(buffer, 0, 10000) ' Read the data in buffer
Response.OutputStream.Write(buffer, 0, length) ' Write the data to the current output stream.
Response.Flush() ' Flush the data to the HTML output.
ReDim buffer(10000) ' Clear the buffer
dataToRead = dataToRead - length
Else
dataToRead = -1 'prevent infinite loop if user disconnects
End If
End While
Don't bother with dataToRead. Keep reading until length is 0 (i.e streamer.Read() has returned 0). This means you've reached the end of the stream.
My VB is a bit rusty, but I think the loop should look something like this:
finished = False
While Not finished ' Read the bytes.
If Response.IsClientConnected Then ' Verify that the client is connected.
length = streamer.Read(buffer, 0, 10000) ' Read the data in buffer
If length > 0 Then
Response.OutputStream.Write(buffer, 0, length) ' Write the data to the current output stream.
Response.Flush() ' Flush the data to the HTML output.
ReDim buffer(10000) ' Clear the buffer
Else
finished = True
End If
Else
finished = True
End If
End While