如何在 ASP.Net Core MVC 中实现文件上传
http://
ASP.Net
Core MVC 实现了将
上传文件
直接映射到 model 中,只要这个 model 实现了
IFormFile
接口即可,回想一下,
model binding
的作用就是将 Request 映射到 Action 方法参数的过程,这样就简化了原来需要直接对 Request 的访问,同时也方便后续做单元测试,本篇中的
IFormFile
接口就简化了对 Request 中的 file 访问。
上传一个文件
在这一节中我们将会演示如何通过 IFromFile 接口来对接 client 上传一个或者多个文件,先看一下
IFromFile
接口的定义。
public interface IFormFile
string ContentType { get; }
string ContentDisposition { get; }
IHeaderDictionary Headers { get; }
long Length { get; }
string Name { get; }
string FileName { get; }
Stream OpenReadStream();
void CopyTo(Stream target);
Task CopyToAsync(Stream target, CancellationToken cancellationToken = null);
然后我们创建一个 FileUploadController
类,构建一个 UploadFile 方法来接收 client 上传的文件。
public class FileUploadController : Controller
[HttpPost("UploadFile")]
public async Task<IActionResult> UploadFile(IFormFile iFormFile)
if (iFormFile == null || iFormFile.Length == 0)
return Content("No file selected for upload.");
var filePath = Path.GetTempFileName();
using (var stream = new FileStream(filePath, FileMode.Create))
await iFormFile.CopyToAsync(stream);
return RedirectToAction("Home");
从上面代码可以看到,UploadFile 方法中使用了 IFormFile 实例作用参数,如果 iFormFile 里无数据或者空引用就返回 No file selected for upload.
反之就保存文件并跳转到 Home 页。
如果有多文件上传需求,可以将 IFromFile 改成数组形式,如下代码所示:
[HttpPost("UploadFiles")]
public async Task<IActionResult> UploadFiles(List<IFormFile> iFormFiles)
var filePath = Path.GetTempFileName();
foreach (var iFormFile in iFormFiles)
if (iFormFile.Length > 0)
using (var stream = new FileStream(filePath, FileMode.Create))
await iFormFile.CopyToAsync(stream);
return RedirectToAction("Home");
上面代码用了 GetTempFileName()
来获取临时文件,这里有一个坑需要注意,如果这个路径下的临时文件超过 65535 的话将会抛出异常,解决办法就是:
- 在处理完之后删除临时文件。
- 将文件保存在你指定的地方。
下载 file
要想从 http://ASP.Net Core MVC 中下载文件,考虑如下代码:
public async Task<IActionResult> DownloadFile(string path, string filename)
if (filename == null || filename.Length == 0)
return Content("No file selected for download.");
var filePath = Path.Combine(path, filename);
var memoryStream = new MemoryStream();
using (var stream = new FileStream(filePath, FileMode.Open))
await stream.CopyToAsync(memoryStream);
memoryStream.Position = 0;
return File(memoryStream, "text/plain", Path.GetFileName(path));
在 DownloadFile 方法中使用了 CopyToAsync
方法将文件 copy 到 MemoryStream 中,然后通过返回 FileStreamResult 将文件流返回给客户端。
创建一个 Razor View
接下来创建一个 Razor View 用来做文件上传的界面,在 View 界面中添加如下代码:
ViewData["Title"] = "Home Page";
<div class="text-center">
<form asp-controller="FileUpload" asp-action="UploadFile" method="post"
enctype="multipart/form-data">
<input type="file" name="iFormFile" />
<button type="submit">Upload File</button>
</form>
<form asp-controller="FileUpload" asp-action="UploadFiles" method="post"
enctype="multipart/form-data">
<input type="file" name="iFormFiles" multiple />
<button type="submit">Upload Files</button>
</form>