Uploading and Downloading in MVC Step-by-Step

Introduction
 
I hope you all are fine. Today we will learn how to perform upload and download operations in MVC. Please refer to the step-by-step approach in learning Model View Controller if you are new to MVC. Our MVC Master, Shivprasad koirala has explained the concepts in a perfect way. 
Please see this article in my blog here 
 
This article has been selected as Article Of The Day for October 6th 2015 in Asp.net Community 
 
Please see this article in my blog here 
 
Download the source code
 
You can always download the source code from Uploading and Downloading in MVC Step-by-Step 
 
Background 
 
Some days earlier, I got a requirement to develop a upload and download mechanism in my MVC application. After completing it perfectly, I decided to share it with you all.
 
Using the code
 
Before moving further into the details, let us first list the key points we will explain in this article:
  • Create a MVC application.
  • Create a controller.
  • Create View depending on the controller.
  • Change the RouteConfig as needed.
  • Create ActionResult for the actions.
  • Create a folder where we need to save the downloaded files. 
Let us start with creating a controller called "myAction".
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.IO;  
  4. using System.Linq;  
  5. using System.Web;  
  6. using System.Web.Mvc;  
  7.   
  8. namespace UploadDownloadInMVC.Controllers  
  9. {  
  10.     public class myActionController : Controller  
  11.     {  
  12.         //  
  13.         // GET: /myAction/  
  14.   
  15.   
  16.     }  
  17. }  
As you can see that the controller is empty; we will be writing the action results next. 
  1. public ActionResult Index()  
  2.        {  
  3.            foreach (string upload in Request.Files)  
  4.            {  
  5.                if (Request.Files[upload].FileName != "")  
  6.                {  
  7.                    string path = AppDomain.CurrentDomain.BaseDirectory + "/App_Data/uploads/";  
  8.                    string filename = Path.GetFileName(Request.Files[upload].FileName);  
  9.                    Request.Files[upload].SaveAs(Path.Combine(path, filename));  
  10.                }  
  11.            }  
  12.            return View("Upload");  
  13.        }  
The action result shown above is for index. So, whenever the application loads, the action result will be fired. For that, the following changes should be done for RouteCofig.
  1. public class RouteConfig  
  2.     {  
  3.         public static void RegisterRoutes(RouteCollection routes)  
  4.         {  
  5.             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");  
  6.   
  7.             routes.MapRoute(  
  8.                 name: "Default",  
  9.                 url: "{controller}/{action}/{id}",  
  10.                 defaults: new { controller = "myAction", action = "Index", id = UrlParameter.Optional }  
  11.             );  
  12.         }  
  13.     }  
As you can see in the Index Action,  we are checking whether the request parameter contains the files. If it exists, we will save the selected file to the directory 
/App_Data/uploads/ (that we need to manually create in our application). After returning to the view Upload, we need to set the Upload view.
 
Upload View
 
The following is the code for the Upload view.
  1. @{  
  2.     ViewBag.Title = "Upload";  
  3. }  
  4.   
  5. <h2>Upload</h2>  
  6. <script src="~/Scripts/jquery-1.11.1.min.js"></script>  
  7. <script>  
  8.     $(document).ready(function () {  
  9.         $('#btnUploadFile').on('click'function () {  
  10.             var data = new FormData();  
  11.             var files = $("#fileUpload").get(0).files;  
  12.             // Add the uploaded image content to the form data collection  
  13.             if (files.length > 0) {  
  14.                 data.append("UploadedImage", files[0]);  
  15.             }  
  16.             // Make Ajax request with the contentType = false, and procesDate = false  
  17.             var ajaxRequest = $.ajax({  
  18.                 type: "POST",  
  19.                 url: "myAction/Index",  
  20.                 contentType: false,  
  21.                 processData: false,  
  22.                 data: data  
  23.             });  
  24.   
  25.             ajaxRequest.done(function (xhr, textStatus) {  
  26.                 // Do other operation  
  27.             });  
  28.         });  
  29.     });  
  30. </script>  
  31. <input type="file" name="FileUpload1" id="fileUpload" /><br />  
  32. <input id="btnUploadFile" type="button" value="Upload File" />  
  33. @Html.ActionLink("Documents""Downloads")  
In the upload view, we have the following:  
  1. File uploader
  2. Upload button
  3. Ajax call to the controller ( myAction/Index)
 Here, we are adding the uploaded image content to the form data collection.
  1. var data = new FormData();  
  2.            var files = $("#fileUpload").get(0).files;  
  3.            // Add the uploaded image content to the form data collection  
  4.            if (files.length > 0) {  
  5.                data.append("UploadedImage", files[0]);  
  6.            }  
Once the data is added to the form data collection, we will pass the data to the controller via ajax call. Sounds cool, right? If the procedure goes well, we will see the output as follows.
 
 
When you choose the file and click upload, your selected file will be uploaded to the folder "uploads" as we have set it in the controller.
 
We have finished the process of uploading files. We will now move to the downloading section. This is the right time to add the remaining actions to our controller. The following is the code.
  1. public ActionResult Downloads()  
  2.         {  
  3.             var dir = new System.IO.DirectoryInfo(Server.MapPath("~/App_Data/uploads/"));  
  4.             System.IO.FileInfo[] fileNames = dir.GetFiles("*.*"); List<string> items = new List<string>();  
  5.             foreach (var file in fileNames)  
  6.             {  
  7.                 items.Add(file.Name);  
  8.             }  
  9.             return View(items);  
  10.         }  
  11.   
  12.         public FileResult Download(string ImageName)  
  13.         {  
  14.             var FileVirtualPath = "~/App_Data/uploads/" + ImageName;  
  15.             return File(FileVirtualPath, "application/force-download", Path.GetFileName(FileVirtualPath));  
  16.         }  
Do you remember that we have set an action link in the "Upload" View?
  1. @Html.ActionLink("Documents""Downloads")  
Next, if we click on the "Documents" link, our Action Result Downloads will be fired, right? Now, the following code will explain what is happening here.
  1. var dir = new System.IO.DirectoryInfo(Server.MapPath("~/App_Data/uploads/"));  
  2.             System.IO.FileInfo[] fileNames = dir.GetFiles("*.*"); List<string> items = new List<string>();  
  3.             foreach (var file in fileNames)  
  4.             {  
  5.                 items.Add(file.Name);  
  6.             }  
  7.             return View(items);  
We are considering all the attached files, adding the file information to a list and returning this list to the view "Download". Next, here's the need to set another view. The following code is for the Download View.
 
Download View
  1. @{  
  2.     ViewBag.Title = "Downloads";  
  3. }  
  4.   
  5. <h2>Downloads</h2>  
  6.   
  7.   
  8. @model List<string>  
  9. <h2>Downloads</h2>  
  10. <table>  
  11.     <tr>  
  12.         <th>File Name</th>  
  13.         <th>Link</th>  
  14.     </tr>  
  15.     @for (var i = 0; i <= Model.Count - 1; i++)  
  16.     {   
  17.         <tr>  
  18.             <td>@Model[i].ToString() </td>  
  19.             <td>@Html.ActionLink("Download""Download"new { ImageName = @Model[i].ToString() }) </td>  
  20.         </tr>  
  21.     }  
  22. </table>  
Here, we are taking the information (that we are sending from the controller) about the uploaded files and creating the Html.ActionLinks dynamically.
 
Please note that we are adding the Image name to the  action. Here is the output after performing the operations.
 
 
 
As in the preceding image, when you mouse over the link, it will show the image name along with the controller URL. Click on the link to download the file. So simple, right?

Conclusion

I hope you liked the article. Please provide your valuable feedback; it matters a lot. You can download the source code to determine more.

Point of interest

MVC, MVC Upload, MVC Download, File Uploading Using MVC, File Downloading Using MVC 

 

Up Next
    Ebook Download
    View all
    Learn
    View all