Uploading files with ASP.NET Core 1.0 MVC

Handling file uploads has changed quite a bit in ASP.NET Core. This article looks at the new objects that have been introduced to replace the old System.Web based approach from previous versions of ASP.NET. **Updated to RTM**

In previous versions of ASP.NET, an uploaded file was represented by an instance of System.Web.HttpPostedFileBase. This has been replaced in ASP.NET Core by IFormFile, which is found in the Microsoft.AspNet.Http namespace. It shares a few of the same properties and methods as its predecessor, but it also has its differences, as can best be shown by example.

First, here's an upload form that uses the new TagHelpers introduced in ASP.NET Core MVC:

<form method="post" asp-action="Index" asp-controller="Home" enctype="multipart/form-data">
    <input type="file" name="files" multiple/>
    <input type="submit" value="Upload" />
</form>

To enable file uploading, you need to ensure that the form's method is set to post and that the enctype is set to multipart/form-data. This example takes advantage of the HTML5 multiple attribute on the file input which enables multiple file uploading via a single control.

file upload

The form posts back to the Index method on the Home controller:

public class HomeController : Controller
{
    private IHostingEnvironment _environment;

    public HomeController(IHostingEnvironment environment)
    {
        _environment = environment;
    }
    public IActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public async Task<IActionResult> Index(ICollection<IFormFile> files)
    {
        var uploads = Path.Combine(_environment.WebRootPath, "uploads");
        foreach (var file in files)
        {
            if (file.Length > 0)
            {
                using (var fileStream = new FileStream(Path.Combine(uploads, file.FileName), FileMode.Create))
                {
                    await file.CopyToAsync(fileStream);
                }
            }
        }
        return View();
    }
}

The controller has a constructor added that takes an IHostingEnvironment as a parameter. IHostingEnvironment is a service that provides some useful environment information such as the current file path to the wwwroot folder via the WebRootPath property. This is required when specifying the location for saving uploaded files. One version of the Index method is restricted to supporting HTTP Post operations and it takes a collection of IFormFile objects as a parameter. The name of the parameter is the same as the name attribute provided to the file upload in the HTML form ("files") so that model binding will take care of matching uploaded files to the method parameter.

IFormFile objects share some properties and methods with their predecessors. IFormFile objects have a Length property instead of ContentLength. The FileName property was added in RC2. Before that, you had to parse the ContentDisposition headers to obtain that information. Note that in RC2, there is also a Name property. This actually returns the value of the name attribute on the upload control. Having obtained the actual file name, the code saves the uploaded file to the specified location asynchronously using the CopyToAsync method. This was added in RC2, replacing a SaveAsAsync method.

Summary

Handling uploaded files in ASP.NET Core is a little different to previous versions. This article explored the new APIs and provided a brief overview of the properties and methods of most interest.

A sample application is available at Github.