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,而不是在控制台上的操作了,毕竟学编程就是要多加练习,在实践中发现 ...
随机推荐
- ApiPost自动化测试基础之:如何使用测试校验(测试用例)?
我们在<ApiPost的环境变量的定义和使用>和<ApiPost自动化测试基础之:接口参数依赖的情景处理>分别讲解了ApiPost环境变量的定义.使用以及基于环境变量的接口参数 ...
- [POI2013]Łuk triumfalny
[POI2013]Łuk triumfalny 题目大意: 一棵\(n(n\le3\times10^5)\)个结点的树,一开始\(1\)号结点为黑色.\(A\)与\(B\)进行游戏,每次\(B\)能选 ...
- hdu 4169 二分匹配最大独立集 ***
题意:有水平N张牌,竖直M张牌,同一方向的牌不会相交.水平的和垂直的可能会相交,求最少踢出去几张牌使剩下的牌都不相交. 二分匹配 最小点覆盖=最大匹配. 链接:点我 坐标点作为匹配的端点 #inclu ...
- python tcp 实时抓包
问题:之前我们系统上线后,因为是旧的系统,没有加统计的功能,比如用户喜欢那个页面,是哪些用户再访问,接口的负载能力等等. 解决办法:1,现有代码更改,添加功能.现有代码侵入太多,工作量比较大 2,想到 ...
- 狗日的系统之家下载的Windows 10 1803/1809系统不干净,捆绑自动安装腾讯关键等软件
特此记录一下,如果网友看到这篇文章请不要下载它们家的,捆绑软件,并且安装自动设置了账号,这还不是修改,是啥? 我们都知道现在iso文件基本都是网友自行制作的,从微软下载的文件自行制作成iso,也就是现 ...
- Auto Layout on iOS Versions prior to 6.0
使用XCODE5.0,出现这个小错误... 解决办法: 选中你的XIB或storyboard,如下图 再查看右边属性栏 去掉最下边的Use Autolayout ,完成. 转:http://blog. ...
- C#编程(十七)----------Object类
Object类 它是.NET Framework 中所有类的最终基类:它是类型层次结构的根.也就是说所有的类都拥有object类的方法,并能重写,调用. object的构造函数:public Obje ...
- Atlassian JIRA Change IP
Oracle Linux 6.8 Atalssian JIRA 7 原来IP: 192.168.10.200 改新IP: 192.168.12.200 重新跑应用报错,如下所示: 官方提示应用连接不上 ...
- css 滚动条样式
1,Overflow内容溢出时的设置 overflow 水平及垂直方向内容溢出时的设置 overflow-x 水平方向内容溢出时的设置 overflow-y 垂直方向内容溢出时的设置 以上三个属性设置 ...
- ZooKeeper_客户端工具zkCli.sh使用
#一.命令 [root@VM_31_182_centos bin]# ./zkCli.sh -server 127.0.0.1:2181 #二.帮助命令 help #三.创建.修改.删除.退出de ...