Uploading multiple files with ASP.NET MVC

4.37 (30 votes)

I have looked at uploading individual files and downloading multiple files in MVC, and I've had a few requests recently asking me to complete the series by showing how to upload multiple files in an ASP.NET MVC application.

When designing the form for uploading, you can choose from a number of approaches. You can use plain HTML elements. If you know that your users are using browsers that implement the HTML5 file API, you can provide a single file input with the multiple attribute:

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

This enables multiple file selection, but is not available in Internet Explorer 9 or below. It is available in most other modern browsers. One alternative is to provide a number of inputs for users of IE9 or lower. You can selectively choose to display the single input with the multiple attribute set or multiple individual inputs based on the features supported by the browser. Here's the HTML part, including the form declaration which requires the method to be set to POST and an enctype set to multipart/form-data for file uploading to work:

@using (Html.BeginForm("Multiple", "Home", FormMethod.Post, new { enctype = "multipart/form-data" })) { 
    <div id="multiple">
        <input type="file" class="multiple" name="files" multiple />
    </div>
    <div id="single">
        <input type="file" class="single" name="files" /><br />
        <input type="file" class="single" name="files" /><br />
        <input type="file" class="single" name="files" /><br />
    </div>
    <button class="btn btn-default">Upload</button>   
}

And here's the jquery code that switches between the two options:

@section Scripts{
    <script type="text/javascript">
        $(function () {
            if(window.FileReader != null){
                $('#single').hide();
                $('.single').prop('disabled', true);
            } else {
                $('#multiple').hide();
                $('.multiple').prop('disabled', true);
            }
        });
    </script>
}

Browsers that implement the HTML5 file API include a component called Filereader. If this is null, the browser doesn't provide the required support and the input with the multiple attribute is disabled and hidden.

Files are uploaded to the server in the Request.Files collection, each one of which is mapped to an HttpPostedFileBase object by the default MVC model binder. Therefore, the controller action that is tasked to process the uploaded files needs a parameter that represents a collection of HttpPostedFileBase objects. This can be a property on a model, or a simple List<HttpPosteFileBase>parameter. The following action takes each file and saves it with a new name generated from a Guid to a folder called "uploads":

[HttpPost]
public ActionResult Multiple(IEnumerable<HttpPostedFileBase> files)
{
    foreach (var file in files)
    {
        if (file != null && file.ContentLength > 0)
        {
            file.SaveAs(Path.Combine(Server.MapPath("/uploads"), Guid.NewGuid() + Path.GetExtension(file.FileName)));
        }
    }
    return View();
}

An HttpPostedFileBase collection is created and sized to the number of uploads on a form regardless whether the user populated it, or the number of files uploaded if the multiple attribute approach is used. So when testing to see if a file has been uploaded, you should check to see if it is null before testing to see if the ContentLength is greater than 0. If you prefer to save the files in a database, either as binary data or pointers to files in the file system you can read how to do that from my previous article on file uploading: ASP.NET MVC 5 with EF 6 - Working With Files.

Summary

This brief article shows how to upload multiple files in an ASP.NET MVC application by using only HTML solutions (no Flash). It describes the multiple attribute available as part of HTML5 and shows how to fallback to an alternative solution in the cases where the browser lacks the required support.

Date Posted:
Last Updated:
Posted by:
Total Views to date: 69465

1 Comment

- Manoj Kulkarni

Nice article. Thank you for sharing.

Recent Comments

Thomas 05/03/2018 00:59
In response to I'm Not Writing A Book On Razor Pages
There's a typo on this page: = true)] should be [BindProperty(SupportsGet = true)]...

Rolf Herbert 04/03/2018 19:25
In response to I'm Not Writing A Book On Razor Pages
So is MS deprecating razor Web Pages..? Is it dead..? I wish they would stop killing things so its...

Borut 17/02/2018 12:59
In response to I'm Not Writing A Book On Razor Pages
Mike, is it possible that Web Pages and Razor Pages "live" together in one web application? I a I...

hrboyce 09/02/2018 04:44
In response to I'm Not Writing A Book On Razor Pages
Mike, First thanks for doing this but I have to ask, any chance you would consider converting one of...

aziz sallam 07/02/2018 10:18
In response to I'm Not Writing A Book On Razor Pages
u are a great man...

Satyabrata Mohapatra 31/01/2018 11:36
In response to I'm Not Writing A Book On Razor Pages
This is a great news!!!! Thanks...

tangdf 30/01/2018 07:25
In response to I'm Not Writing A Book On Razor Pages
=> { o.ConfigureFilter(new IgnoreAntiforgeryTokenAttribute()); }); The extension method does...

Obinna Okafor 30/01/2018 04:02
In response to I'm Not Writing A Book On Razor Pages
Thank you very much. I would like to see a project built from scratch using Razor Pages. And it show...

rachida Dukes 31/10/2017 13:52
In response to Customising Identity in Razor Pages
Thanks again for this wonderful tutorial. I followed all the steps in this section called: Adding...

Rachida 31/10/2017 12:06
In response to Customising Identity in Razor Pages
Thanks very much for this wonderful tutorial, it helped a lot....