Download Files in ASP.NET MVC 3 using Controller Action
Posted by: Mahesh Sabnis ,
on 5/10/2012,
in
Category ASP.NET MVC
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:
namespace MVC3_Returning_Files.Models
{
public class DataClasses
{
public List<FileNames> GetFiles()
{
List<FileNames> lstFiles = new List<FileNames>();
DirectoryInfo dirInfo = new DirectoryInfo(HostingEnvironment.MapPath("~/Files"));
int i = 0;
foreach (var item in dirInfo.GetFiles())
{
lstFiles.Add(new FileNames() {
FileId = i + 1, FileName = item.Name, FilePath = dirInfo.FullName+@"\"+item.Name});
i = i + 1;
}
return lstFiles;
}
}
public class FileNames
{
public int FileId { get; set; }
public string FileName { get; set; }
public string FilePath { get; set; }
}
}
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:
namespace MVC3_Returning_Files.Controllers
{
public class ReportsController : Controller
{
DataClasses objData;
public ReportsController()
{
objData = new DataClasses();
}
//
// GET: /Reports/
public ActionResult Index()
{
var files = objData.GetFiles();
return View(files);
}
public FileResult Download(string id)
{
int fid = Convert.ToInt32(id);
var files = objData.GetFiles();
string filename = (from f in files
where f.FileId == fid
select f.FilePath).First();
string contentType = "application/pdf";
//Parameters to file are
//1. The File Path on the File Server
//2. The content type MIME type
//3. The parameter for the file save by the browser
return File(filename, contentType,"Report.pdf");
}
}
}
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:
model IEnumerable<MVC3_Returning_Files.Models.FileNames>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
FileId
</th>
<th>
FileName
</th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.FileId)
</td>
<td>
@Html.DisplayFor(modelItem => item.FileName)
</td>
<td>
@Html.ActionLink("Download", "Download", new { id = item.FileId })
</td>
</tr>
}
</table>
Step 6: Add the following Action link in the menucontainer <div> of the _Layout.cshtml:
<li>@Html.ActionLink("Reports", "Index", "Reports")</li>
Step 7: Run the application and you will find the Report menu. After clicking on it, the Index page will display all the Files as shown below:
Click on the Download link and you will get a download box as shown below (Note: I am using IE9)
Conclusion
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.
The entire source code of this article can be downloaded from GitHub
This article has been editorially reviewed by Suprotim Agarwal.
C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.
We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).
Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.
Click here to Explore the Table of Contents or Download Sample Chapters!
Was this article worth reading? Share it with fellow developers too. Thanks!
Mahesh Sabnis is a DotNetCurry author and a Microsoft MVP having over two decades 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), and Front-end technologies like Angular and React. Follow him on twitter @
maheshdotnet or connect with him on
LinkedIn