Upload multiple files and display progress-bar with Ajax correctly in Asp.Net MVC

by Sachin Singh


Posted on Saturday, 27 March 2021

Tags: Upload multiple files and display progress-bar with Ajax correctly in Asp.Net MVC Multiple file upload with progressbar in MVC file upload in mvc file upload with ajax in mvc

For beginners uploading multiple files with Ajax and displaying a real time progress-bar is often a challenge. Because they don't know how to send files with Ajax from view to controller.

The key is, we should always use Javascript's FormData() to send every control's value from view to controller whenever an input type file is being used.

Our final output should look like below.

File upload with progress-bar
File upload with progress-bar

Step 1. Create a Model class as shown below.


    public class FileUpload
    {
        public List<HttpPostedFileBase> Files { get; set; }
        public string Name { get; set; }
    }


Step 2. create two Action methods, one which will return view and another for uploading files.


      public ActionResult FileUpload()
        {
            return View();
        }

        public ActionResult fileSave(FileUpload fileupload)
        {
            try
            {
                if (fileupload.Files.Count() > 0)
                {
                    foreach (var file in fileupload.Files)
                    {
                        string filename = file.FileName;
                        var ext = filename.Substring(filename.LastIndexOf(".") + 1).ToLower();
                        if (ext.ToLower() == "jpeg" || ext.ToLower() == "jpg" || ext.ToLower() == "png")
                        {
                            string path = Server.MapPath("~/uploads/" + filename);
                            file.SaveAs(path);
                            // Todo: for database 
                            string uploadedBy = fileupload.Name;
                            string FilePath = path;
                            //Save fields to database
                            //
                        }
                    }
                    return Json("data saved");
                }
            }
            catch
            {
                return Json("error");
            }

            return Json("something went wrong");     
        }

Step 3. Write the necessary JavaScript code as shown below.

The code is simple, at first we are checking the file extension and returning false if file is not of proper type to prevent the server trip, then we are appending the input values into FormData. To display the real time uploading status in the progress bar we are using the loaded and total property of event object. Finally an Ajax call is being issued to submit the data to the controller.




 <!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

<!-- jQuery library -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
@{
    ViewBag.Title = "FileUpload";
}

<h2>FileUpload</h2>
<table class="table table-resonsive table-bordered">
    <tr>
        <td>Uploaded By</td>
        <td><input type="text" name="Name" value="" id="txtName" /></td>
    </tr>

    <tr>
        <td>Upload File</td>
        <td><input id="file" name="Files" type="file" multiple />
            <div class="progress">
                <div id="pb" class="progress-bar" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
                    0%
                </div>
            </div>
        </td>

    </tr>
    <tr>
        <td colspan="2"><input type="button" value="button" class="btn btn-success" onclick="return Save()"/></td>
    </tr>
</table>
<script>
   function Save() 
   {   
        debugger;
        var fileUpload = $("#file").get(0);
        var files = fileUpload.files;
        var data = new FormData();

        for (var i = 0; i < files.length; i++) {
            var fname = files[i].name;
            var re = /(\.doc|\.docx|\.pdf|\.xlxs)$/i;
            if (!re.exec(fname)) {
                alert("File extension not supported!");
                return false;
            } 
     else {
                data.append("Files", files[i]);        
            }       
        }
        data.append("Name", $("#txtName").val());
        $.ajax({
            xhr: function () {
                var xhr = new window.XMLHttpRequest();
                xhr.upload.addEventListener("progress", function (e) {
                    if (e.lengthComputable) {
                        var loaded = e.loaded;
                        var total = e.total;
                        var percent = Math.round((loaded / total) * 100);
                      
                        $("#pb").attr("aria-valuenow", percent).css("width", percent + "%").text(percent + "%");
                    };

                });
                return xhr;
            },
            type: "post",
            url: "/Home/fileSave",
            data: data,
            dataType: "json",
            contentType: false, // Not to set any content header  
            processData: false,
            cache: false,
            success: function (ss) {

                alert(ss);
            }
        });   
    };
</script>

At this moment run the application, you will be successfully able to upload multiple files.

File upload with progress-bar controller side
File upload with progress-bar controller side