Currently, I was trying to write an ASP.Net application that involved a user clicking a ASP.Net button control

 
 
 
 
 
 

C#

 
<asp:Button ID="btnDownload" runat="server" Text="Download File" OnClick="btnDownload_Click"/>
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.

Download button onclick event handler

 
 
 
 
 
 

C#

 
protected void btnDownload_Click(object sender, EventArgs e)
{
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

Former DownloadFile generic handler

 
 
 
 
 
 

C#

 
<%@ WebHandler Language="C#" class="DownloadFile" %>

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

httpRuntime maxRequestLength and executionTimeout settings

 
 
 
 
 
 

C#

 
<httpRuntime maxRequestLength="600000" executionTimeout="7200"/>
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

Current DownloadFile.ashx generic handler

 
 
 
 
 
 

C#

 
<%@ WebHandler Language="C#" class="DownloadFile" %>

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)的更多相关文章

  1. [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 ...

  2. [转] Spring MVC sample application for downloading files

    http://www.codejava.net/frameworks/spring/spring-mvc-sample-application-for-downloading-files n this ...

  3. TCP连接的状态与关闭方式及其对Server与Client的影响

    TCP连接的状态与关闭方式及其对Server与Client的影响 1. TCP连接的状态 首先介绍一下TCP连接建立与关闭过程中的状态.TCP连接过程是状态的转换,促使状态发生转换的因素包括用户调用. ...

  4. navicat 连接sqlserver提示要安装 sql server native client

    navicat 连接sqlserver提示要安装 sql server native client 解决方法:其实navicat自带sqlncli_x64.msi,就在安装目录下,安装后问题解决!

  5. 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 ...

  6. 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 ...

  7. Netty4.0学习笔记系列之一:Server与Client的通讯

    http://blog.csdn.net/u013252773/article/details/21046697 本文是学习Netty的第一篇文章,主要对Netty的Server和Client间的通讯 ...

  8. 浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6627260 在前面一篇文章浅谈Service ...

  9. 基于winsocket的框体Server和Client

    前面学了一点Winsock的知识,会编写简单的Server和Client,现在就想通过VS2008编写框体的Server和Client,而不是在控制台上的操作了,毕竟学编程就是要多加练习,在实践中发现 ...

随机推荐

  1. ApiPost自动化测试基础之:如何使用测试校验(测试用例)?

    我们在<ApiPost的环境变量的定义和使用>和<ApiPost自动化测试基础之:接口参数依赖的情景处理>分别讲解了ApiPost环境变量的定义.使用以及基于环境变量的接口参数 ...

  2. [POI2013]Łuk triumfalny

    [POI2013]Łuk triumfalny 题目大意: 一棵\(n(n\le3\times10^5)\)个结点的树,一开始\(1\)号结点为黑色.\(A\)与\(B\)进行游戏,每次\(B\)能选 ...

  3. hdu 4169 二分匹配最大独立集 ***

    题意:有水平N张牌,竖直M张牌,同一方向的牌不会相交.水平的和垂直的可能会相交,求最少踢出去几张牌使剩下的牌都不相交. 二分匹配 最小点覆盖=最大匹配. 链接:点我 坐标点作为匹配的端点 #inclu ...

  4. python tcp 实时抓包

    问题:之前我们系统上线后,因为是旧的系统,没有加统计的功能,比如用户喜欢那个页面,是哪些用户再访问,接口的负载能力等等. 解决办法:1,现有代码更改,添加功能.现有代码侵入太多,工作量比较大 2,想到 ...

  5. 狗日的系统之家下载的Windows 10 1803/1809系统不干净,捆绑自动安装腾讯关键等软件

    特此记录一下,如果网友看到这篇文章请不要下载它们家的,捆绑软件,并且安装自动设置了账号,这还不是修改,是啥? 我们都知道现在iso文件基本都是网友自行制作的,从微软下载的文件自行制作成iso,也就是现 ...

  6. Auto Layout on iOS Versions prior to 6.0

    使用XCODE5.0,出现这个小错误... 解决办法: 选中你的XIB或storyboard,如下图 再查看右边属性栏 去掉最下边的Use Autolayout ,完成. 转:http://blog. ...

  7. C#编程(十七)----------Object类

    Object类 它是.NET Framework 中所有类的最终基类:它是类型层次结构的根.也就是说所有的类都拥有object类的方法,并能重写,调用. object的构造函数:public Obje ...

  8. Atlassian JIRA Change IP

    Oracle Linux 6.8 Atalssian JIRA 7 原来IP: 192.168.10.200 改新IP: 192.168.12.200 重新跑应用报错,如下所示: 官方提示应用连接不上 ...

  9. css 滚动条样式

    1,Overflow内容溢出时的设置 overflow 水平及垂直方向内容溢出时的设置 overflow-x 水平方向内容溢出时的设置 overflow-y 垂直方向内容溢出时的设置 以上三个属性设置 ...

  10. ZooKeeper_客户端工具zkCli.sh使用

    #一.命令 [root@VM_31_182_centos bin]# ./zkCli.sh -server 127.0.0.1:2181   #二.帮助命令 help #三.创建.修改.删除.退出de ...