File uploads in ASP.NET Core

Just wrote down something I had to went through with students in one of my classes – making file uploads work in ASP.NET Core application. Here are samples of single and multiple file uploads using simple controller actions.

Creating upload action and view

I start with clean ASP.NET Core application and add Upload() action to HomeController.

public IActionResult Upload()
{
    return View();
}

It’s empty and returns just view to upload files.

Next thing is to create Upload view with following markup:

<h1>File upload</h1>

@*
    To post files to server we need form with post method,
    and additionally browser must use multipart/form-data
    encoding. Otherwise file will not be sent.
*@
<form method="post" enctype="multipart/form-data">
    <input type="file" name="file" /> 
    <button type="submit">Upload</button>
</form>

@*
    If upload succeeded we will show nice message to user.
*@
@if(ViewBag.Message != null)
{
    <div class="alert alert-success" style="margin-top:20px">
        @ViewBag.Message
    </div>
}

Saving uploaded file

To save file in server we need another controller action in HomeController. I name it again Upload() but this one is a little different.

[HttpPost]
public IActionResult Upload(IFormFile file)
{
    // Extract file name from whatever was posted by browser
    var fileName = System.IO.Path.GetFileName(file.FileName);

    // If file with same name exists delete it
    if(System.IO.File.Exists(fileName))
    {
        System.IO.File.Delete(fileName);
    }

    // Create new local file and copy contents of uploaded file
    using(var localFile = System.IO.File.OpenWrite(fileName))
    using(var uploadedFile = file.OpenReadStream())
    {
        uploadedFile.CopyTo(localFile);
    }

    ViewBag.Message = "File successfully uploaded";

    return View();
}

Notice [HttpPost] attribute on top of new Upload() action – it tells ASP.NET to use this action when browser makes POST request to Upload() method. New Upload() method has also argument named as file. Take a look at view markup above – we named file upload field as file too. ASP.NET will match these two automatically for us.

Uploading multiple files

To upload multiple files we doesn’t necessarily need multiple file upload fields. We can use one field for multiple files. For this to happen we need to add “multiple” attribute to file field. Also I will change name of file upload field from “file” to “files”.

<input type="file" name="files" multiple />

Our file field works now with one file and multiple files.

We need to reflect this also in Upload() action. The change is simple – we just change method argument from single file to array and save files down in foreach loop.

[HttpPost]
public IActionResult Upload(IFormFile[] files)
{
    // Iterate through uploaded files array
    foreach (var file in files)
    {
        // Extract file name from whatever was posted by browser
        var fileName = System.IO.Path.GetFileName(file.FileName);

        // If file with same name exists delete it
        if (System.IO.File.Exists(fileName))
        {
            System.IO.File.Delete(fileName);
        }

        // Create new local file and copy contents of uploaded file
        using (var localFile = System.IO.File.OpenWrite(fileName))
        using (var uploadedFile = file.OpenReadStream())
        {
            uploadedFile.CopyTo(localFile);
        }
    }

    ViewBag.Message = "Files successfully uploaded";

    return View();
}

This is all we need to do to upload multiple files.

NB! To try file uploads out, run application in browser and type Home/Upload/ to the end of address. Browser will show upload view. Select some files from computer to upload and click Upload button. Uploaded files will be visible in Visual Studio solution explorer after successful upload.

Wrapping up

Handling file uploads in ASP.NET Core is easy. It’s easier than it was with previous ASP.NET versions. We just use IFormFile as upload method argument and ASP.NET Core puts uploaded file or files there. It’s easy to work also with multiple files – we can use array of IFormFile and iterate through it using foreach loop. It’s simple, clean and nice.

Liked this post? Empower your friends by sharing it!

Gunnar Peipman

Gunnar Peipman is ASP.NET, Azure and SharePoint fan, Estonian Microsoft user group leader, blogger, conference speaker, teacher, and tech maniac. Since 2008 he is Microsoft MVP specialized on ASP.NET.

    5 thoughts on “File uploads in ASP.NET Core

    • November 4, 2019 at 11:21 am
      Permalink

      It should be noted that you should not use the file name for storing files locally as in your example. An attacker could delete files on the web server by crafting a file name that matches an existing file on the server.

    • November 4, 2019 at 11:37 am
      Permalink

      In practice it depends. There are few cases:

      – further sanitizing of file names
      – generating new file names

      For sample to try out on local box the solution works well.

    • November 14, 2019 at 1:40 am
      Permalink

      Hi,

      How to send json in the same time?
      Is there a way to be able to send for example a list of user and a list of files associated to each of them?

    • November 14, 2019 at 6:11 am
      Permalink

      Hi,

      you can create a form with file uploads and regular form fields if you need. If you have something in JSON then it can be some regular text field.

    Leave a Reply

    Your email address will not be published. Required fields are marked *