Click here to Skip to main content
15,880,725 members
Articles / Web Development / HTML

Multiple file uploads with progress bar using classic ASP.NET and C#

Rate me:
Please Sign up or sign in to vote.
4.33/5 (8 votes)
1 Sep 2010CPOL4 min read 105.7K   6.7K   55   11
In web applications, displaying a progress bar is necessary while uploading files. This article helps in creating a progress bar for single file and multi-file uploads in ASP.NET 2.0.

Introduction

This article gives readers a fair idea of how to create a progress bar while uploading single/multiple files in a web based application. We had a requirement in one of our projects for displaying a continuous progress bar along with percentage uploaded. This article will provide you great information about how to create such a control using ASP.NET 2.0 and .NET Framework 2.0. Also, the page on which this control is deployed will not be posted back as the solution uses an IFrame to load the file upload control. Users are free to access other parts of the page while the upload is still in progress.

Background

My initial idea was to calculate the progress amount on the server side and use a JavaScript timer function to read the server-side progress amount, with the XMLHttpRequest object to update the progress bar from the client side. That didn't go well, as it shows either a 0% or a complete 100%, but not continuous progress. I used Mozilla Firebug to trace out the XMLHttpRequest object requesting pattern. For some reason, XMLHttpRequests are queued until the server-side event handler finishes its execution, in this case, the upload, so either it hits before the server-side upload started, or after the server-side upload is completed. Hence the progress bar either shows 0 or 100%.

I would like to say thanks to Mr. Munur Shaik: http://www.c-sharpcorner.com/UploadFile/munnamax/ProgressBar07062007122251PM/ProgressBar.aspx for the idea, which I have reused for creating my progress bar. Also, I would like to convey my thanks to our architect Anil Sistla for supporting me in completing the solution. I hope this article will definitely save a lot of time for those who are looking for a similar solution.

Using the code

Shown below is the source code structure. The UploadProgressBar.ascx file is the user control that displays a single file upload control with Add/Remove buttons. The Add button adds the multiple file upload controls, whereas Remove clears the file upload controls one at a time.

CodeStructure.jpg

The image below shows the initial file upload screen. FileUploadIframe.aspx contains a simple HTML IFrame tag to load the control page (FileUpload.aspx). Here, IFrame is used because the main page on which the multi-file upload is placed should not postback when the Upload button is pressed.

FileUploadControlUi.jpg

During file upload, the progress bar looks like below:

MultiFileUploadProgressBar.jpg

Below is the code for creating the progress bar:

C#
public void CreateProgress(HttpFileCollection fileCollection)
{
    //string fileName, int id, string progressAmount
    StringBuilder sbProgress = new StringBuilder();
    sbProgress.Append("<html><head><LINK REL=StyleSheet " + 
      "HREF='StyleSheet1.css' TYPE='text/css' /></head>  <body>");
    sbProgress.Append("<script src='JScript1.js' type='text/javascript'>" + 
      "</script><table id='mainTable' border='1'>");
    for (int i = 0; i < fileCollection.Count; i++)
    {
        string strProgressBarId = "progressBar" + i;
        string strPercentageId = "percentage" + i;
        string fileName = fileCollection[i].FileName;
        sbProgress.Append("<tr><td><p>" + fileName + 
          "</p></td><td><div id='xxx' " + 
          "style='background-color:White; width: 100px;height:15px; " + 
          "border-color:Black;border-width:thin;border-style:solid'>");
        sbProgress.Append("<div class='progressBar'  id='" + 
          strProgressBarId + "' ></div></div></td>" + 
          "<td><p><div id='" + strPercentageId + 
          "'></div></p></td></tr>");
    }
    sbProgress.Append("</table>");
    for (int i = 0; i < fileCollection.Count; i++)
    {
        sbProgress.Append("<script type='text/javascript'> " + 
          "SetProgressBarProgressAmount(" + i + ",0 );</script>");
    }
    sbProgress.Append(PrepareTheGridHtml());
    sbProgress.Append("</body></html>");

    HttpContext.Current.Response.Write(sbProgress.ToString());
    HttpContext.Current.Response.Flush();
}

This method (CreateProgress()) basically pumps the progress bar HTML to the output stream to create an empty progress bar. In the above code, SetProgressBarProgressAmount(..) is a JavaScript method which takes two parameters: the first parameter is the ID of the progress bar, which is necessary in case multiple progress bars are displayed, and the second parameter is the progress amount. As the file downloads to the server, this progress bar will be set as per the percentage of download, and finally, when the file download completes, it will be set to 100%. In the case of multiple file uploads, multiple progress bars will be displayed, one per each file, and the files will be uploaded to the server one by one, and we can see the progress amount of each file. Below is the code which downloads the file to the server:

C#
public void DownloadTheFileToServer(HttpPostedFile file, int id)
{
    Stream stream = null;
    FileStream fs = null;

    #region File Download Code goes here
    try
    {
        string strFileName = System.IO.Path.GetFileName(file.FileName);
        int contentLength = file.ContentLength;
        stream = file.InputStream;
        long totalUploadSize = stream.Length;
        int bufferSize = 0;
        //less than 1kB
        if (totalUploadSize <= 1024)
        {
            bufferSize = 1024;
        }
        //less than 4kB but more than 1kB
        else if (bufferSize <= 4096)
        {
            bufferSize = 4096;
        }
        //less than 8Kb
        else if (bufferSize <=8192)
        {
            bufferSize = 8192;
        }
        else
        {
            bufferSize = 16384;
        }

        byte[] b = new byte[1024];
        int tripDownloadSize = 0;
        long totalDownloadedSize = 0;
        float Percentage = 0;
        bool isNewFile = true;
        string fileStoreLocation = 
          ConfigurationManager.AppSettings["FileStoreLocation"];
        fs = new FileStream(fileStoreLocation + strFileName, FileMode.Append);

        //Uplaods 8Kb at a time
        while ((tripDownloadSize = stream.Read(b, 0, 1024)) > 0)
        {
            fs.Write(b, 0, tripDownloadSize);
            totalDownloadedSize += tripDownloadSize;
            Percentage = (int)(totalDownloadedSize * 100) / totalUploadSize;
            setProgressBar(id, Percentage.ToString());
            System.Threading.Thread.Sleep(100);
            isNewFile = false;
        }

    }
    catch (Exception objException)
    {
        throw objException;
    }
    finally
    {
        if (stream != null)
        {
            stream.Close();
            stream.Dispose();
        }
        if (fs != null)
        {
            fs.Close();
            fs.Dispose();
        }
    }
    #endregion
}

In the above method, based on the size of the file, I have written logic to decide the buffer size of the stream, but it is entirely up to the developer how he wants to set the buffer size (byte array size) for reading the input stream. This article mainly concentrates on how to create/update the progress while the file download is in progress. In the above code, inside the while loop, every time the total downloaded size is calculated, and the percentage of the download will be determined by the formula: total downloaded size / total file size * 100. Using the method setProgressBar(id, Percentage), we can set the progress for a particular progress bar with id as id. Below is the code for the SetProgressBar method:

C#
public static void setProgressBar(int id, string progressAmount)
{
    StringBuilder sb = new StringBuilder();
    sb.Append("&lt;body&gt;&lt;script type='text/javascript'&gt;" +
       "SetProgressBarProgressAmount(" + id + ",'" + progressAmount + 
       "'); &lt;/script&gt;&lt;/body&gt;");
    HttpContext.Current.Response.Write(sb.ToString());
    HttpContext.Current.Response.Flush();
}

Search the web.config file for the entry FileStoreLocation under appsettings, and set it to the local folder location on your machine; files uploaded through the file upload control will be downloaded to this location.

Disclaimer

This article gives a starting point to users who want to have a similar kind of progress bar. This control is not ready for production deployment. This progress bar control does not take many things into consideration like file types that can be uploaded to the server etc. It is entirely the responsibility of the developer to make sure it fits to his requirements. I am not responsible for any kind of damage that this control causes to the application/product into which this product is being integrated. I expect the developer to evaluate the solution completely before integrating/using with existing applications.

License

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


Written By
Architect
India India
I have around 9 years of experience in Microsoft technologies, .Net 2.0,3.5, Asp.net MVC developed small to medium scale products using Silverlight 2.0, Asp.net Ajax technologie and Javascript frameworks.

Comments and Discussions

 
QuestionDisplay progress bar aside upload button Pin
Prajakta V C14-Jul-14 2:51
Prajakta V C14-Jul-14 2:51 
QuestionMultiple file upload Pin
Member 887609729-Apr-12 18:37
Member 887609729-Apr-12 18:37 
AnswerRe: Multiple file upload Pin
Ramu Sangabathula Original12-Mar-14 6:27
Ramu Sangabathula Original12-Mar-14 6:27 
QuestionProgress bar show only after Files post back to Server, but not when files uploading to server Pin
lmheah22-Mar-11 20:25
lmheah22-Mar-11 20:25 
AnswerRe: Progress bar show only after Files post back to Server, but not when files uploading to server Pin
Ramu Sangabathula Original12-Mar-14 6:25
Ramu Sangabathula Original12-Mar-14 6:25 
QuestionMissing Reference? Pin
Offr0ad9-Nov-10 20:46
Offr0ad9-Nov-10 20:46 
AnswerRe: Missing Reference? Pin
Ramu Sangabathula Original10-Nov-10 5:14
Ramu Sangabathula Original10-Nov-10 5:14 
Hi,

Please remove the missing reference, it should work fine, also if possible please check in the latest code.

Thanks,
Ram
GeneralMy vote of 1 Pin
aaa20096-Nov-10 20:23
aaa20096-Nov-10 20:23 
AnswerRe: My vote of 1 Pin
Ramu Sangabathula Original8-Nov-10 5:09
Ramu Sangabathula Original8-Nov-10 5:09 
GeneralError converting this project into VS.Net 2005 Pin
aaa20096-Nov-10 20:22
aaa20096-Nov-10 20:22 
GeneralCode snippets Pin
Not Active1-Sep-10 9:09
mentorNot Active1-Sep-10 9:09 

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.