[ASP.NET]How to implement file upload and download in ASP.NET MVC
[ASP.NET]How to implement file upload and download in ASP.NET MVC
File upload/download is very useful functionality in web application. Here is a simple implementation of file upload/download in ASP.NET MVC 1.0. The sample use a “FileManager” controller to handle file download and file upload requests. And for download, I created a custom ActionResult class to stream out the binary file content.
FileManager Controller
namespace MVCFileWeb.Controllers { /// <summary> /// MVC Controller class for file upload and download /// </summary> public class FileManagerController : Controller { /// <summary> /// default Action /// </summary> public ActionResult Index() { var files = from f in System.IO.Directory.GetFiles( Server.MapPath("~/App_Data/download/"), "*.*", SearchOption.TopDirectoryOnly) select System.IO.Path.GetFileName(f); return View(files.ToList()); } /// <summary> /// action for file download /// </summary> public ActionResult Download(string fn) { string pfn = Server.MapPath("~/App_Data/download/" + fn); if (!System.IO.File.Exists(pfn)) { throw new ArgumentException("Invalid file name or file not exists!"); } return new BinaryContentResult(){ FileName = fn, ContentType="application/octet-stream", Content= System.IO.File.ReadAllBytes(pfn) };
} /// <summary> /// Action for file upload /// </summary> [AcceptVerbs(HttpVerbs.Post)] public ActionResult Upload() { string upload_dir = Server.MapPath("~/app_data/upload/");
foreach (string f in Request.Files.Keys) { if (Request.Files[f].ContentLength > 0) Request.Files[f].SaveAs(upload_dir + System.IO.Path.GetFileName(Request.Files[f].FileName)); } return RedirectToRoute(new { Action = "Index", Controller = "FileManager" }); } } } |
Custom ActionResult for file download(as binary stream):
namespace MVCFileWeb { public class BinaryContentResult: ActionResult { public BinaryContentResult() {} public string ContentType { get; set; } public string FileName { get; set; } public byte[] Content { get; set; } public override void ExecuteResult(ControllerContext context) {
context.HttpContext.Response.ClearContent(); context.HttpContext.Response.ContentType = ContentType;
context.HttpContext.Response.AddHeader("content-disposition",
"attachment; filename=" + FileName); context.HttpContext.Response.BinaryWrite(Content); context.HttpContext.Response.End(); } } } |
Index view of FileManager Controller:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<List<String>>" %> <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> Index </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <h2>Files for download</h2> <%foreach (string file in Model) {%> <br /><%= Html.ActionLink(file,"Download",new {Action="Download", fn=file}) %>
<%} %> <hr /> <h2>Upload new file</h2>
<% using (Html.BeginForm("Upload", "FileManager", FormMethod.Post, new { enctype = "multipart/form-data" })) {%> <br />File1:<input type="file" name="file1" id="file1" /> <br />File2:<input type="file" name="file2" id="file2" />
<br /><input type="submit" value="submit" /> <% } %> </asp:Content> |
You can also get the complete solution in attachment.