Click here to Skip to main content
Click here to Skip to main content

Multiple File Upload in MVC

, 7 Aug 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
Multiple file upload in MVC

Introduction

I had a requirement in MVC 4 application - A multi file uploader control that has options:

  • Select multiple files at a time
  • Select from different folder
  • List all selected files
  • Remove files from the list (Filtering)
  • When submitting - Save only filtered one
  • Get page model also in the Action
  • Save attachments after saving the model saving or some business logic

Issues I Faced

I was getting the partial needs - Uploader control, but Model received is empty - at Action in our controller.
When Model is filled, the filtered list is incorrect (deleted files also appeared).

How I Solved It

I created a JS script that will make the <input type="file" /> control get recreated and preserve the HttpPostedFileBase files + removed/filtered files in a Hidden field - This maintains the filtration in deleting selected files also.

When user puts some files in the fileupload control, "onchange" event, it will hide the control and create a similar control and place there and allow users to select again. The selected files are taken and maintained in a Hidden field appending its names. With these names - we can filter the posted files list (List) in our action. So while passing Model - keep this hidden field value.

Using the Code

Please find the source code attached here for the full demo.

I will explain how it works. See the code snippet below.

Given below is the snippet of HTML that has a fileUploader and a button that submits to our server action.

@using (Html.BeginForm("UploadAction", "Home", 
FormMethod.Post, new { enctype = "multipart/form-data", id = "frmID" }))
{
    @Html.HiddenFor(i => i.FilesToBeUploaded)

    <div class="labelstyle">
        <label>Files</label>
    </div>

    <div id="uploaders">
        <input type="file" id="fileToUpload" 
        name="fileUpload" multiple="multiple" style="float: left;" />
        <br />
        <span id="spnFile" style="float: left; color: #FF0000"></span>
        @Html.ValidationMessage("File")
        @Html.Hidden("hdnFileUpload")
    </div>
    <br />
 <div class="col-lg-6">
        <button class="btn btn-primary" id="btnAddIssue" type="submit">Submit</button>
    </div>
    <br />
    <div class="control-section" style="padding: 0px;">
        <div id="selectedFiles"></div>
    </div>
}

This portion is the script that is responsible for creation of the multi file upload and hiding the previous uploader + storing the filtered attachments to a hidden field.

<script src="~/Scripts/jquery-1.7.1.js"></script>

<script>
    var nowTemp = new Date();
    var now = new Date(nowTemp.getFullYear(), nowTemp.getMonth(), nowTemp.getDate(), 0, 0, 0, 0);
    var files;
    var storedFiles = [];
    var upc = 0;   

    $(function () {

        $(":file").attr('title', '  ');
        var $loading = $('#loadingDiv').hide();

        $("input[id^='fileToUpload']").change(function (e) {
            doReCreate(e);
        });

        selDiv = $("#selectedFiles");
    });

    function doReCreate(e) {
        alert('a');
        upc = upc + 1;
        handleFileSelect(e);

        $("input[id^='fileToUpload']").hide();

        $('<input>').attr({
            type: 'file',
            multiple: 'multiple',
            id: 'fileToUpload' + upc,
            class: 'fUpload',
            name: 'fileUpload',
            style: 'float: left',
            title: '  ',
            onchange: "doReCreate(event)"

        }).appendTo('#uploaders');
    }

    function handleFileSelect(e) {

        //selDiv.innerHTML = ""; storedFiles = []; 
        selDiv = document.querySelector("#selectedFiles");

        if (!e.target.files) return;

        //selDiv.innerHTML = "";
        files = e.target.files;

        for (var i = 0; i < files.length; i++) {
            //if (i == 0) { selDiv.innerHTML = ""; storedFiles = []; }
            var f = files[i];
            selDiv.innerHTML += "<div>" + f.name + 
            "<a onclick='removeAtt(this)'> X </a></div>";
            storedFiles.push(f.name);
        }
        $('#@Html.IdFor(i => i.FilesToBeUploaded)').val(storedFiles);
    }

    function removeAtt(t) {
        var serEle = $(t).parent().text().slice(0, -3);
        var index = storedFiles.indexOf(serEle);
        if (index !== -1) {
            storedFiles.splice(index, 1);
        }
        $(t).parent().remove();

        $('#@Html.IdFor(i => i.FilesToBeUploaded)').val(storedFiles);

    }
</script>

And find the server code, where it receives the model + hidden element and the full attachments that we need.

 [HttpPost]
        public ActionResult UploadAction(AnyModel model, List<HttpPostedFileBase> fileUpload)
        {
            // Your Code - / Save Model Details to DB

            // Handling Attachments - 
            foreach (HttpPostedFileBase item in fileUpload)
            {
                if (Array.Exists(model.FilesToBeUploaded.Split(','), s => s.Equals(item.FileName)))
                {
                    //Save or do your action -  Each Attachment ( HttpPostedFileBase item ) 
                }
            }
            return View("Index");
        }

Also, if style "X" to remove selected files, update your script code accordingly.

Points of Interest

This is a simple one and a tricky approach - Recommended for small file(s) size - But can be any number of files .

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Rigin VP
Software Developer
India India
Am a software Developer
Working in mostly MS Platform, interested in scripting languages.
 
Am from South India - Kerala Smile | :)
 
Rigin
Follow on   Twitter   Google+   LinkedIn

Comments and Discussions

 
Questioncant save files to folder PinmemberMember 1154163220-Mar-15 8:17 
Questionsame code are not working with IE 9.0 Pinmemberkrish.singh17-Feb-15 10:28 
AnswerRe: same code are not working with IE 9.0 PinmemberRigin VP17-Feb-15 10:38 
GeneralRe: same code are not working with IE 9.0 Pinmemberkrish.singh18-Feb-15 6:03 
Questionsame code isnt working in IE PinmemberNaveen861117-Feb-15 9:11 
AnswerRe: same code isnt working in IE PinmemberRigin VP17-Feb-15 9:35 
Generalhow to store image PinmemberPrasenjit Dutta6-Jan-15 1:05 
AnswerRe: how to store image PinmemberRigin VP6-Jan-15 3:29 
GeneralRe: how to store image PinmemberRigin VP11-Jan-15 20:19 
QuestionSource Code is missing Pinmembersnprani27-Oct-14 20:55 
QuestionMissing Zip PinmemberMember 1116390218-Oct-14 19:01 
AnswerRe: Missing Zip PinmemberMember 1116390218-Oct-14 19:03 
Answerfile upload [modified] PinmemberChhabra_Ankur30-Sep-14 22:38 
GeneralRe: file upload PinmemberRigin VP1-Oct-14 2:28 
GeneralRe: file upload PinmemberChhabra_Ankur6-Oct-14 21:05 
GeneralRe: file upload PinmemberRigin VP6-Oct-14 23:26 
QuestionZip file is missing... Pinmembersiva000725-Sep-14 1:11 
AnswerRe: Zip file is missing... PinmemberChhabra_Ankur1-Oct-14 2:15 
GeneralRe: Zip file is missing... PinmemberRigin VP1-Oct-14 2:27 
QuestionZip File Not Available Pinmembersurajemo19-Sep-14 9:09 
QuestionProject file missing Pinmembersakonj16-Sep-14 22:23 
Questionzip file missing PinmemberMember 30894158-Sep-14 0:12 
QuestionProject file missing PinmemberMember 1104852031-Aug-14 5:12 
SuggestionRe: Project file missing PinmemberRigin VP31-Aug-14 22:56 
GeneralRe: Project file missing Pinmembermajestique23-Oct-14 7:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.150327.1 | Last Updated 7 Aug 2014
Article Copyright 2014 by Rigin VP
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid