X

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!
Categories: ASP.NET

View Comments (7)

  • 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.

  • 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.

  • 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?

  • 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.

  • Dont think you should create local copies of those files if the content has to be streamed to database. Then the memory stream of the file is enough to stream that to database.

  • Hi. Can you tell me how to upload files to asp.net core from windows forms ?? Really need. But you can’t implement it

Related Post