Click here to Skip to main content
15,916,398 members
Articles / Web Development / ASP.NET
Tip/Trick

How to Download Large Files from ASP.NET Web Forms or MVC?

Rate me:
Please Sign up or sign in to vote.
4.86/5 (18 votes)
15 Nov 2014CPOL1 min read 53.3K   27   4
How to download large files from ASP.NET Web Forms (Download.aspx or Download.ashx) or ASP.NET MVC

Introduction

Sometimes in ASP.NET Web Forms or ASP.NET MVC applications, you put some of your secured files in a secured folder such as App_Data because you do not want users to have direct access to these files for downloading. In this situation, you write a Download.aspx file or Download.ashx http handler (in ASP.NET Web Forms), or create a download action (in ASP.NET MVC) that users can just download these files with these capabilities. There are a lot of source codes for this situation. But! If the size (length) of these files be large, for example, over 100 MB! We have two main problems.

First, we caused a very huge overhead to the server’s CPU and RAM and second, if some user tried to download a large file and after a few seconds he avoided to download the file resume, your application does not know it!

So in the below source code, I optimized the download progress, so the code get a few bytes from the file and send it to the user (client). By the way, if after a few seconds, the user (client) avoided to download the file resume, the below code recognizes it and stops sending the file resume.

Note: The below code is an action for ASP.NET MVC applications, But you can write it in Download.aspx or Download.ashx files in your ASP.NET Web Forms applications.

Using the Code

C#
/// <summary>
/// Download Large Files! For example more than 100MB!
/// </summary>
public void Download(int id)
{
    // **************************************************
    string strFileName =
        string.Format("{0}.zip", id);

    string strRootRelativePathName =
        string.Format("~/App_Data/Files/{0}", strFileName);

    string strPathName =
        Server.MapPath(strRootRelativePathName);

    if (System.IO.File.Exists(strPathName) == false)
    {
        return;
    }
    // **************************************************

    System.IO.Stream oStream = null;

    try
    {
        // Open the file
        oStream =
            new System.IO.FileStream
                (path: strPathName,
                mode: System.IO.FileMode.Open,
                share: System.IO.FileShare.Read,
                access: System.IO.FileAccess.Read);

        // **************************************************
        Response.Buffer = false;

        // Setting the unknown [ContentType]
        // will display the saving dialog for the user
        Response.ContentType = "application/octet-stream";

        // With setting the file name,
        // in the saving dialog, user will see
        // the [strFileName] name instead of [download]!
        Response.AddHeader("Content-Disposition", "attachment; filename=" + strFileName);

        long lngFileLength = oStream.Length;

        // Notify user (client) the total file length
        Response.AddHeader("Content-Length", lngFileLength.ToString());
        // **************************************************

        // Total bytes that should be read
        long lngDataToRead = lngFileLength;

        // Read the bytes of file
        while (lngDataToRead > 0)
        {
            // The below code is just for testing! So we commented it!
            //System.Threading.Thread.Sleep(200);

            // Verify that the client is connected or not?
            if (Response.IsClientConnected)
            {
                // 8KB
                int intBufferSize = 8 * 1024;

                // Create buffer for reading [intBufferSize] bytes from file
                byte[] bytBuffers =
                    new System.Byte[intBufferSize];

                // Read the data and put it in the buffer.
                int intTheBytesThatReallyHasBeenReadFromTheStream =
                    oStream.Read(buffer: bytBuffers, offset: 0, count: intBufferSize);

                // Write the data from buffer to the current output stream.
                Response.OutputStream.Write
                    (buffer: bytBuffers, offset: 0,
                    count: intTheBytesThatReallyHasBeenReadFromTheStream);

                // Flush (Send) the data to output
                // (Don't buffer in server's RAM!)
                Response.Flush();

                lngDataToRead =
                    lngDataToRead - intTheBytesThatReallyHasBeenReadFromTheStream;
            }
            else
            {
                // Prevent infinite loop if user disconnected!
                lngDataToRead = -1;
            }
        }
    }
    catch { }
    finally
    {
        if (oStream != null)
        {
            //Close the file.
            oStream.Close();
            oStream.Dispose();
            oStream = null;
        }
        Response.Close();
    }
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer Sematec Ins.
Iran (Islamic Republic of) Iran (Islamic Republic of)
My experiences are:

HTML 5.0, CSS 3.0
JQuery, Angular JS, Bootstrap

MVC 5.0, WEB API, c#

My Site URLs:
http://www.IranianExperts.ir
http://www.IranianExperts.com

My Yahoo Group URL: http://groups.yahoo.com/group/iranianexperts

Mobile: 0098-912-108-7461
Address: Tehran, Tehran, Iran

Comments and Discussions

 
QuestionInterrupted downloads on IE 10 Pin
kantv18-Jan-16 4:48
kantv18-Jan-16 4:48 
AnswerRe: Interrupted downloads on IE 10 Pin
Dharmik Shah9-Apr-18 21:29
Dharmik Shah9-Apr-18 21:29 
QuestionNice Download Solution. Can you put some light on the Upload process as well of file size >100 MB ? Pin
Member 1051180617-Nov-14 19:42
Member 1051180617-Nov-14 19:42 
GeneralMy vote of 4 Pin
Assil17-Nov-14 1:13
professionalAssil17-Nov-14 1:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.