Downloading files from a server to client, using ASP.Net, when file size is too big for MemoryStream using Generic Handlers (ashx)
Currently, I was trying to write an ASP.Net application that involved a user clicking a ASP.Net button control
C#
|
1
2
3
|
<asp:Button ID="btnDownload"runat="server"Text="Download File"OnClick="btnDownload_Click"/>
|
Once the control is clicked the back end stores the users information (first name, last name, email address, phone number, etc…) to a database. After that information is stored to a database, the system would then allow the user to download the file through an generic handler (.ashx file). The file size that was to be downloaded is 600MB.
C#
{
connectionString = WebConfigurationManager.ConnectionStrings["connectionstring"].ConnectionString;
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand("UserDownloadedFile", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@Guid", SqlDbType.UniqueIdentifier));
cmd.Parameters["@Guid"].Value = new Guid(ViewState["Guid"].ToString());
try
{
int rowsAffected;
rowsAffected = 0;
con.Open();
rowsAffected = cmd.ExecuteNonQuery();
if (rowsAffected > 0)
{
Response.Redirect("http://localhost/someWebApp/DownloadFile.ashx");
}
else
{
// Something went wrong.
}
}
catch (SqlException exception)
{
// Log exception
}
finally
{
con.Close();
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
protectedvoidbtnDownload_Click(objectsender,EventArgse)
{
connectionString=WebConfigurationManager.ConnectionStrings["connectionstring"].ConnectionString;
SqlConnection con=newSqlConnection(connectionString);
SqlCommand cmd=newSqlCommand("UserDownloadedFile",con);
cmd.CommandType=CommandType.StoredProcedure;
cmd.Parameters.Add(newSqlParameter("@Guid",SqlDbType.UniqueIdentifier));
cmd.Parameters["@Guid"].Value=newGuid(ViewState["Guid"].ToString());
try
{
introwsAffected;
rowsAffected=0;
con.Open();
rowsAffected=cmd.ExecuteNonQuery();
if(rowsAffected>0)
{
Response.Redirect("http://localhost/someWebApp/DownloadFile.ashx");
}
else
{
// Something went wrong.
}
}
catch(SqlException exception)
{
// Log exception
}
finally
{
con.Close();
}
}
|
Once the database is updated, I call the DownloadFile.ashx generic handler. Upon execution of the generic handler I received the following “OutOfMemoryException” error

This was a result from the following generic handler I was using
C#
using System;
using System.IO;
using System.Web;
public class DownloadFile : IHttpHandler {
public void ProcessRequest(HttpContext context)
{
string mediaName = "myFile.zip"; // 600MB in file size
if (string.IsNullOrEmpty(mediaName))
{
return;
}
string destPath = context.Server.MapPath("~/Downloads/" + mediaName);
// Check to see if file exist
FileInfo fi = new FileInfo(destPath);
// If the file exist on the server then add it to the database
if (fi.Exists)
{
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.AppendHeader("Content-Length", fi.Length.ToString());
HttpContext.Current.Response.ContentType = "application/x-zip-compressed";
HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment; filename=" + mediaName);
HttpContext.Current.Response.BinaryWrite(ReadByteArryFromFile(destPath));
HttpContext.Current.Response.End();
}
}
private byte[] ReadByteArryFromFile(string destPath)
{
byte[] buff = null;
FileStream fs = new FileStream(destPath, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
long numBytes = new FileInfo(destPath).Length;
buff = br.ReadBytes((int)numBytes);
return buff;
}
public bool IsReusable
{
get
{
return false;
}
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
<%@WebHandlerLanguage="C#"Class="DownloadFile"%>
usingSystem;
usingSystem.IO;
usingSystem.Web;
publicclassDownloadFile:IHttpHandler{
publicvoidProcessRequest(HttpContext context)
{
stringmediaName="myFile.zip";// 600MB in file size
if(string.IsNullOrEmpty(mediaName))
{
return;
}
stringdestPath=context.Server.MapPath("~/Downloads/"+mediaName);
// Check to see if file exist
FileInfo fi=newFileInfo(destPath);
// If the file exist on the server then add it to the database
if(fi.Exists)
{
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.AppendHeader("Content-Length",fi.Length.ToString());
HttpContext.Current.Response.ContentType="application/x-zip-compressed";
HttpContext.Current.Response.AppendHeader("Content-Disposition","attachment; filename="+mediaName);
HttpContext.Current.Response.BinaryWrite(ReadByteArryFromFile(destPath));
HttpContext.Current.Response.End();
}
}
privatebyte[]ReadByteArryFromFile(stringdestPath)
{
byte[]buff=null;
FileStream fs=newFileStream(destPath,FileMode.Open,FileAccess.Read);
BinaryReader br=newBinaryReader(fs);
longnumBytes=newFileInfo(destPath).Length;
buff=br.ReadBytes((int)numBytes);
returnbuff;
}
publicboolIsReusable
{
get
{
returnfalse;
}
}
}
|
This handler worked in the past, for very small files. The last time I was using this the file size was about 300MB. My friend @homeraguas reminded me that I might needed to check my web.config file to be sure that the following maxRequestLength and executionTimeout was set. It wasn’t in the web.config file. So I added the following
C#
|
1
2
3
|
<httpRuntime maxRequestLength="600000"executionTimeout="7200"/>
|
Recompiled and published, then gave it another go. Still, I came across the “OutOfMemoryException” error. I looked around the net and came across this blog’s article utilizing the following method Reponse.TransmitFile();
The HttpReponse.TransmitFile()method basically states it “Writes the specified file directly to an HTTP response output stream without buffering it in memory.”
This makes sense to me, since the file I want to transfer is 600MB and I do not think the current server I am writing this web application for does not have adequate resources available. So the revision to the code I wrote/used is as follows
C#
using System;
using System.IO;
using System.Web;
public class DownloadFile : IHttpHandler {
public void ProcessRequest(HttpContext context)
{
string mediaName = "myFile.zip"; // 600MB in file size
if (string.IsNullOrEmpty(mediaName))
{
return;
}
string destPath = context.Server.MapPath("~/Downloads/" + mediaName);
// Check to see if file exist
FileInfo fi = new FileInfo(destPath);
try
{
if (fi.Exists)
{
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment; filename=" + fi.Name);
HttpContext.Current.Response.AppendHeader("Content-Length", fi.Length.ToString());
HttpContext.Current.Response.ContentType = "application/octet-stream";
HttpContext.Current.Response.TransmitFile(fi.FullName);
HttpContext.Current.Response.Flush();
}
}
catch (Exception exception)
{
HttpContext.Current.Response.ContentType = "text/plain";
HttpContext.Current.Response.Write(exception.Message);
}
finally
{
HttpContext.Current.Response.End();
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
<%@WebHandlerLanguage="C#"Class="DownloadFile"%>
usingSystem;
usingSystem.IO;
usingSystem.Web;
publicclassDownloadFile:IHttpHandler{
publicvoidProcessRequest(HttpContext context)
{
stringmediaName="myFile.zip";// 600MB in file size
if(string.IsNullOrEmpty(mediaName))
{
return;
}
stringdestPath=context.Server.MapPath("~/Downloads/"+mediaName);
// Check to see if file exist
FileInfo fi=newFileInfo(destPath);
try
{
if(fi.Exists)
{
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.AppendHeader("Content-Disposition","attachment; filename="+fi.Name);
HttpContext.Current.Response.AppendHeader("Content-Length",fi.Length.ToString());
HttpContext.Current.Response.ContentType="application/octet-stream";
HttpContext.Current.Response.TransmitFile(fi.FullName);
HttpContext.Current.Response.Flush();
}
}
catch(Exception exception)
{
HttpContext.Current.Response.ContentType="text/plain";
HttpContext.Current.Response.Write(exception.Message);
}
finally
{
HttpContext.Current.Response.End();
}
}
publicboolIsReusable
{
get
{
returnfalse;
}
}
}
|
The result was that it worked.

What do you guys think? Is this an adequate solution? Have a good one!
Downloading files from a server to client, using ASP.Net, when file size is too big for MemoryStream using Generic Handlers (ashx)的更多相关文章
- [DeploymentService:290066]Error occurred while downloading files from admin server for deployment request "0". Underlying error is: "null"
weblogic 莫名无法启动: <Apr , :: PM CST> <Error> <Deployer> <BEA-> <Failed to i ...
- [转] Spring MVC sample application for downloading files
http://www.codejava.net/frameworks/spring/spring-mvc-sample-application-for-downloading-files n this ...
- TCP连接的状态与关闭方式及其对Server与Client的影响
TCP连接的状态与关闭方式及其对Server与Client的影响 1. TCP连接的状态 首先介绍一下TCP连接建立与关闭过程中的状态.TCP连接过程是状态的转换,促使状态发生转换的因素包括用户调用. ...
- navicat 连接sqlserver提示要安装 sql server native client
navicat 连接sqlserver提示要安装 sql server native client 解决方法:其实navicat自带sqlncli_x64.msi,就在安装目录下,安装后问题解决!
- C Socket Programming for Linux with a Server and Client Example Code
Typically two processes communicate with each other on a single system through one of the following ...
- sql System.Data.SqlClient.SqlError: 无法覆盖文件 'C:\Program Files\Microsoft SQL Server\MSSQL\data\itsm_Data.MDF'。数据库 'my1' 正在使用该文件的解决方案
对数据库备份进行还原时遇到“sql System.Data.SqlClient.SqlError: 无法覆盖文件 'C:\Program Files\Microsoft SQL Server\MSSQ ...
- Netty4.0学习笔记系列之一:Server与Client的通讯
http://blog.csdn.net/u013252773/article/details/21046697 本文是学习Netty的第一篇文章,主要对Netty的Server和Client间的通讯 ...
- 浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6627260 在前面一篇文章浅谈Service ...
- 基于winsocket的框体Server和Client
前面学了一点Winsock的知识,会编写简单的Server和Client,现在就想通过VS2008编写框体的Server和Client,而不是在控制台上的操作了,毕竟学编程就是要多加练习,在实践中发现 ...
随机推荐
- luogu P1502 窗口的星星
题目链接 P1502 窗口的星星 题解 扫描线+线段树 线段树的每一个节点处理的是左边框放在当前x-1位置时的框内星星的亮度大小 按照x坐标进行离散化,得到离散化后每一个坐标x的可影响的范围 维护扫描 ...
- Ⅳ.Catalan数
Catalan数首先是由Euler在精确计算对凸n边形的不同的对角三角形剖分的个数问题时得到的,它经常出现在组合计数问题中. 问题的提出:在一个凸n边形中,通过不相交于n边形内部的对角线,把n ...
- BZOJ.2705.[SDOI2012]Longge的问题(莫比乌斯反演 欧拉函数)
题目链接 \(Description\) 求\[\sum_{i=1}^n\gcd(i,n)\] \(Solution\) \[ \begin{aligned} \sum_{i=1}^n\gcd(i,n ...
- django orm 优化
.markdown-body hr::after,.markdown-body::after{clear:both}.loopLine,.messageLine0{marker-end:"u ...
- 基于Servlet+JSP+JavaBean开发模式的用户登录注册
http://www.cnblogs.com/xdp-gacl/p/3902537.html 一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servlet+JSP+JavaBea ...
- CentOS 7下KVM支持虚拟化/嵌套虚拟化配置
开启虚拟化: cat << EOF > /etc/modprobe.d/kvm-nested.conf options kvm-intel nested=1 options kvm- ...
- GetKeyState(vk_control)
GetKeyState(vk_control) 返回负数 , 说明按键被按下了
- Win10年度更新开发必备:VS2015 正式版下载汇总
============================================================================ 微软在07月20日发布了Visual Stud ...
- Flex+blazeds实现与mySQL数据库的连接(已成功实现此文的例子)
http://bdk82924.iteye.com/blog/1067285 几个下载地址 blazeds_turnkey_3-0-0-544.zip 下载地址:http://download.mac ...
- How To Create A Local Repository For SUSE Linux
原文地址:http://candon123.blog.51cto.com/704299/1009294/ As you know,you can use the yum command to inst ...