Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / All-Topics

Uploading and Downloading in MVC Step-by-Step

4.82/5 (7 votes)
16 Jun 2015CPOL3 min read 34.6K  
Uploading and downloading in MVC

Introduction

In this post, 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.

Background

Some days earlier, I had a requirement to develop an 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 an 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”.

C#
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace UploadDownloadInMVC.Controllers
{
    public class myActionController : Controller
    {
        //
        // GET: /myAction/
    }
}

As you can see that the controller is empty; we will be writing the action results next.

C#
public ActionResult Index()
       {
           foreach (string upload in Request.Files)
           {
               if (Request.Files[upload].FileName != "")
               {
                   string path = AppDomain.CurrentDomain.BaseDirectory + "/App_Data/uploads/";
                   string filename = Path.GetFileName(Request.Files[upload].FileName);
                   Request.Files[upload].SaveAs(Path.Combine(path, filename));
               }
           }
           return View("Upload");
       }

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 made for RouteCofig.

C#
public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "myAction", action = "Index", id = UrlParameter.Optional }
            );
        }
    }

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.

HTML
@{
    ViewBag.Title = "Upload";
}
<h2>Upload</h2>
<script src="~/Scripts/jquery-1.11.1.min.js"></script>
<script>
    $(document).ready(function () {
        $(‘#btnUploadFile’).on(‘click’, function () {
            var data = new FormData();
            var files = $("#fileUpload").get(0).files;
            // Add the uploaded image content to the form data collection
            if (files.length > 0) {
                data.append("UploadedImage", files[0]);
            }
            // Make Ajax request with the contentType = false, and procesDate = false
            var ajaxRequest = $.ajax({
                type: "POST",
                url: "myAction/Index",
                contentType: false,
                processData: false,
                data: data
            });
            ajaxRequest.done(function (xhr, textStatus) {
                // Do other operation
            });
        });
    });
</script>
<input type="file" name="FileUpload1″ id="fileUpload" /><br />
<input id="btnUploadFile" type="button" value="Upload File" />
@Html.ActionLink("Documents", "Downloads")

In the upload view, we have the following:

  • File uploader
  • Upload button
  • Ajax call to the controller (myAction/Index)

Here, we are adding the uploaded image content to the form data collection.

C#
var data = new FormData();
           var files = $("#fileUpload").get(0).files;
           // Add the uploaded image content to the form data collection
           if (files.length > 0) {
               data.append("UploadedImage", files[0]);
           }

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:

Image 1

Image 2

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.

C#
public ActionResult Downloads()
        {
            var dir = new System.IO.DirectoryInfo(Server.MapPath("~/App_Data/uploads/"));
            System.IO.FileInfo[] fileNames = dir.GetFiles("*.*"); List<string> items = new List<string>();
            foreach (var file in fileNames)
            {
                items.Add(file.Name);
            }
            return View(items);
        }
        public FileResult Download(string ImageName)
        {
            var FileVirtualPath = "~/App_Data/uploads/" + ImageName;
            return File(FileVirtualPath, "application/force-download", Path.GetFileName(FileVirtualPath));
        }

Do you remember that we have set an action link in the “Upload” View?

HTML
@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.

C#
var dir = new System.IO.DirectoryInfo(Server.MapPath("~/App_Data/uploads/"));
            System.IO.FileInfo[] fileNames = dir.GetFiles("*.*"); 
            List<string> items = new List<string>();
            foreach (var file in fileNames)
            {
                items.Add(file.Name);
            }
            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

HTML
@{
    ViewBag.Title = "Downloads";
}
<h2>Downloads</h2>
@model List<string>
<h2>Downloads</h2>
<table>
    <tr>
        <th>File Name</th>
        <th>Link</th>
    </tr>
    @for (var i = 0; i <= Model.Count  1; i++)
    {
        <tr>
            <td>@Model[i].ToString() </td>
            <td>@Html.ActionLink("Download", 
            "Download", new { ImageName = @Model[i].ToString() }) </td>
        </tr>
    }
</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.

Image 3

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

License

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