Download Files in ASP.NET MVC 3 using Controller Action

Abstract: The FileResult action that comes out of box with ASP.NET MVC3 provides an easy to use abstraction for downloading files in an ASP.NET MVC application.

Last week I was conducting a training for one of my clients on ASP.NET MVC 3 features. They had a file server, hosting various types of reports and were using an ASP.NET Web Form application as a front-end to download the reports on the client machine. Now since they planned on migrating the ASP.NET WebForms to ASP.NET MVC, they expected a similar functionality in MVC too.

As most of you working on ASP.NET MVC know, the Views are directly controlled by controller action. Every action method from the controller class returns an ActionResult. This itself is an abstract class. We have several classes inherited from it and they are used in specific cases. One of the classes inherited from ActionResult is FileResult. This class is used to send binary file content to the response. In the following sample, we will see how we can leverage the FileResult action to download files in an ASP.NET MVC Web Application.

Step 1: Open VS2010 and create a new ASP.NET MVC 3 project, name it as ‘MVC3_Returning_Files’.

Step 2: In the project, add a new folder and name it as ‘Files’. Add couple of PDF files in it.

Step 3: Right-click on the Models folder and add a new class file, name it as ‘DataClasses.cs’. Add the following classes in it:

The class DataClasses contains ‘GetFiles’ method. This method reads all files from the ‘Files’ folder created in Step 2 and returns a list of files with information as Field, FileName and FilePath declared in FileNames class.

Step 4: Add a new ‘ReportsController’ with the following action methods:

The ‘Download’ action method accepts id (FileId) from the view and queries the Files List returned from the GetFiles method. After querying the List of files, it retrieve the file path. It also defines content type which is MIME type defined content header. This information is required by the browser to decide how to handle file. In this case, it is defined as aPDF. The method returns an object of the type ‘FilePathResult’. This is the class inherited from FileResult. FilePathResult accepts three parameters. The first is the file path of the file which is to be downloaded. The second is the content type. The third parameter is the Download file name. This is an optional parameter, but if passed, then the browser will show the download effect.

Step 5: Add a new Index View using Index action which has some Razor code as shown below:

Mahesh is having 10 years of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) since 2005 and has conducted various Corporate Training programs for .NET Technologies (all versions). Follow him on twitter @maheshdotnet

User Feedback

Comment posted by
Naresh
on Friday, May 11, 2012 2:32 AM

Niceeeee

Comment posted by
mathew
on Tuesday, June 12, 2012 1:02 AM

How can i add multiple files to a single zip file and permits the users to download this zip file?

Comment posted by
Doctor Benigno
on Monday, June 18, 2012 7:10 AM

seems there is a problem in step 5

the view croaks with a CS1963 error , the expression tree cannot contain a dinamic operation.

Seems that the use of the @Html.DisplayFor helper needs something more to run smoothly. If i comment out the uses of the helper , the example runs just fine.

I can upload more than 5MB size files, but i can't able to download that files. Give me the solution.
Thanks,

Comment posted by
a
on Tuesday, July 3, 2012 5:25 AM

a

Comment posted by
Pat M
on Monday, July 9, 2012 7:18 PM

Thanks for the great tutorial. I had been trying to adjust the router to enable downloads of zip files but your method makes a lot more sense. I appreciate the help.

Comment posted by
Triven
on Wednesday, July 18, 2012 5:44 AM

Hi Mahesh,

I am getting the following error
The current request for action 'Download' on controller type mycontroller is ambiguous between the following action methods:
System.Web.Mvc.ActionResult Download() on type myproject.Controllers.mycontroller
System.Web.Mvc.FileResult Download(System.String) on type myproject.Controllers.mycontroller

Need help to resolve the same...

Comment posted by
Triven
on Wednesday, July 18, 2012 6:39 AM

Hi Mahesh,

Just needed to have different names for FileResult and ActionResult

Comment posted by
Triven
on Wednesday, July 18, 2012 6:42 AM

Hi Mahesh,

First issue is resolved , but what if i want to download the file with it's actual extension.?

Can we implement the same with small modification:Instead of this on DataClasses.cs:
DirectoryInfo dirInfo = new DirectoryInfo(HostingEnvironment.MapPath("~/Files"));
----Can we have this change dynamically, like for a controller name 'HR' i want the above dirInfo be :
DirectoryInfo dirInfo = new DirectoryInfo(HostingEnvironment.MapPath("~/Files/HR"));
------
I could write a switch statement to do the above but cant understand how the Razor view be modified?

Since this is my first MVC4 app I am really struggling with the syntax issues etc. Any help is appreciated.

Comment posted by
irshad
on Friday, February 14, 2014 1:03 AM

Hi Mahesh,

If we want to return to view or update view after download, how can we do that?

Here, we are returning "File" directly to browser. So the Ui is not updating.

Plese help.

Comment posted by
priya
on Thursday, March 13, 2014 3:57 AM

good one...

Comment posted by
Lokesh
on Monday, April 14, 2014 1:39 AM

Its very Helpful

Comment posted by
IQRA
on Friday, November 21, 2014 6:43 AM

I have my word template save in my project. i want to use that word template and based on the details on the web form the details have to be saved into that word template and download that template using MVC3.How can i do it ?

Comment posted by
Ram
on Wednesday, February 18, 2015 10:09 PM

When I try downloading a file in a program from server, Content of file is displayed on browser instead of downloading as file. Is there any way to download file on to client system instead displaying content on the browser.
Written code…
var byteArray = Encoding.ASCII.GetBytes(sb.ToString());
var cd = new System.Net.Mime.ContentDisposition
{
FileName = FileName,

Hi, can any one help me how to download a image(certificate) from .cshtml while clicking on Some download image... I written like
<a href="/Upload/@item1.imageUrl.Split('\\').Last()" download>
<img border="0" src="~/CSS/images/download.png" alt="W3Schools" width="50" height="50">
</a>

but it is showing the image in the same tab ... I want it to open in different tab ... pls help me..