asp.net large file download out of memory exception - asp.net

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

Related

Issue with saving files into SQL as varbinary(max)

So, I have a web application that saves some attachments into SQL database as VarBinary(max), everything working smoothly until I realized that when I download the attachment from the database, the file is very big comparing to the original size, so a file with 400KB, the downloaded one would be 5MB! what I'm doing wrong?
The upload code is:
Dim img As FileUpload = CType(FileUpload1, FileUpload)
Dim imgByte As Byte() = Nothing
If img.HasFile AndAlso Not img.PostedFile Is Nothing Then
Dim File As HttpPostedFile = FileUpload1.PostedFile
imgByte = New Byte(File.ContentLength - 1) {}
File.InputStream.Read(imgByte, 0, File.ContentLength)
cmd.Parameters.AddWithValue("#filetype", Path.GetExtension(FileUpload1.FileName).ToLower)
cmd.Parameters.AddWithValue("#attachment", imgByte)
End If
The download code:
Dim imagem As Byte() = CType((dr("attachment")), Byte())
Response.Clear()
Response.AddHeader("Cache-Control", "no-cache, must-revalidate, post-check=0, pre-check=0")
Response.AddHeader("Pragma", "no-cache")
Response.AddHeader("Content-Description", "File Download")
Response.AddHeader("Content-Type", "application/force-download")
Response.AddHeader("Content-Transfer-Encoding", "binary\n")
Dim fileName As String = "attachment; filename=" & "DOC_REFNO_" & "_" & regref_txt.Text.Replace("/", "_") & dr("filetype")
Response.AddHeader("content-disposition", fileName)
Response.BinaryWrite(imagem)
Thank you all.
so I found out that the download code is not correct, I changed it to the following code and worked perfectly.
Dim imagem As Byte() = CType((dr("attachment")), Byte())
Response.Buffer = True
Response.Charset = ""
Response.Cache.SetCacheability(HttpCacheability.NoCache)
Response.ContentType = ContentType
Dim fileName As String = "attachment; filename=" & "DOC_REFNO_" & "_" & regref_txt.Text.Replace("/", "_") & dr("filetype")
Response.AddHeader("content-disposition", fileName)
Response.BinaryWrite(imagem)
Response.Flush()
Response.End()

Why the TransmitFile is not downlaoding the file?

I am downloading a file from folder but this code of me doesn't download. It doesn't throw any error but doesn't download either.
Dim req As WebClient = New WebClient()
Dim response As HttpResponse = HttpContext.Current.Response
Dim filePath As String = "~/Downloads/MyExcelFile.xls"
response.Clear()
response.ClearContent()
response.ClearHeaders()
response.Buffer = True
response.AddHeader("Content-Disposition", "attachment;filename=Filename.extension")
'Dim data As Byte() = req.DownloadData(Server.MapPath(filePath))
'response.BinaryWrite(data)
response.TransmitFile(Server.MapPath(filePath))
'response.End()
try
response.WriteFile("some file");
response.Flush();
response.Close();
also consider Andrew's response on handler type - ashx is usually cleaner, with webform you might have other things that happen during page life cycle.

file deletion not working in asp.net vb

I am using following code for file deletion on server after downloading at client site.
The code is working from visual studio but NOT working when website is hosted even on the coding machine.
'To save the word file at temp location with unique name
Dim varDate As String = DateTime.Now.ToString("yyyyMMdd_hhmmss_fff")
Dim theFileName As String = Server.MapPath("~/Temp/Report_" & varDate & ".docx")
oWord.ActiveDocument.SaveAs(theFileName)
oWord.ActiveDocument.Close()
oWord.Quit()
Dim filefullname As System.IO.FileInfo = New System.IO.FileInfo(theFileName)
Response.Clear()
Response.AddHeader("Content-Disposition", "attachment; filename=Observation_Report.docx")
Response.AddHeader("Content-Length", filefullname.Length.ToString())
Response.ContentType = "application/octet-stream"
Response.WriteFile(filefullname.FullName)
Response.Flush()
System.IO.File.Delete(theFileName)
Response.End()

"Thread is terminated" runtime error when initiating download

The situation:
In a C# web site project I am getting data out of a database and write the required data to an excel file server side, which I then want to offer for downloading.
The problem:
At the end of the code to initiate a download (See below) I get a runtime error that the thread is terminated and no file is offered for downloading.
My code
FileStream fStream = new FileStream(resultFile, FileMode.Open, FileAccess.Read);
byte[] byteBuffer = new byte[(int)fStream.Length];
fStream.Read(byteBuffer, 0, (int)fStream.Length);
fStream.Close();
response.Clear();
response.ContentType = "application/vnd.ms-excel";
response.AddHeader("Content-Length", byteBuffer.Length.ToString());
response.AddHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(resultFile));
response.TransmitFile(resultFile);
response.End();
I hope somebody can help me with this. Thanks in advance :)
I used following code to download Excel
FileStream fs = File.OpenRead(path);
byte[] data = new byte[fs.Length];
fs.Read(data, 0, (int)fs.Length);
Response.Buffer = true;
Response.ContentType = "application/x-msdownload";
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName );
Response.BinaryWrite(data);

How can I load a byte array into excel?

I have a btye array that I would like to load into excel. This will do this in vb.net with visual studio 2008.
How can I load the byte array into Excel via memory or with code?
Here is code, you can try:
Dim bytes() As Byte = CType(dt.Rows(0)("Data"), Byte())
Response.Buffer = True
Response.Charset = ""
Response.Cache.SetCacheability(HttpCacheability.NoCache)
Response.ContentType = dt.Rows(0)("ContentType").ToString()
Response.AddHeader("content-disposition", "attachment;filename="
& dt.Rows(0)("Name").ToString())
Response.BinaryWrite(bytes)
Response.Flush()
Response.End()
Take a look at this very good article explaining every step. At the end of article you will find the code to get Byte array and then get the file
Save and Retrieve Files from SQL Server Database using ASP.Net

Resources