Search code examples
c#jqueryasp.net-mvcpostfiledrop.js

Unable to upload call post for transfering group of files to Action


The problems is that when passing an array of File type objects to MVC model action there is a problem with $.post call

What I am doing is using jquery.filedrop library to drop in multiple times. then, after all of the items are dropped and when button is pressed all of those files are being sent to Action called Upload.

HTML markup:

<h2>Upload</h2>

<legend>Upload a file</legend>
<div class="editor-field">
    <input type="file" id="file" name="file" />
</div>

<h2>Drag & Drop file upload </h2>

<div id="dropArea"></div>

<h4>Uploaded files : </h4>
<ul class="list-group" id="uploadList"></ul>
<input id="submsion" type="submit" />

Javascript code:

$(function () {
            $('#dropArea').filedrop({
                allowedfileextensions: ['.doc', '.docx', '.pdf', '.jpg', '.jpeg', '.png', '.PNG', '.gif', '.txt'],
                maxfiles: 3,
                maxfilesize: 5, // in MB
                dragOver: function () {
                    $('#dropArea').addClass('active-drop');
                },
                dragLeave: function () {
                    $('#dropArea').removeClass('active-drop');
                },
                drop: function () {
                    $('#dropArea').removeClass('active-drop');
                },
                afterAll: function (e) {
                    $('#dropArea').html('file(s) uploaded successfully');
                },
                uploadFinished: function (i, file, response, time) {
                    $('#uploadList').append('<li class="list-group-item">' + file.name + '</li>')
                    addToFilePile(file)
                }
            })
        })

    var arrayOfFiles = [];
    var singularObject;
    $('#file').on('change', function () {
        singularObject = $('#file').val();
    });

    function addToFilePile(file) {
            arrayOfFiles.push(file);
    }

        $('#submsion').click(function () {
            var finalPile = [];
            if (arrayOfFiles != null) {
                finalPile = arrayOfFiles;
                if (singularObject != null) {
                    finalPile.push(singularObject);
                }
        }
            else if (singularObject != null) {
                finalPile = singularObject;
        }

        else {
              //both are empty - do something about it
            }

            console.log(finalPile);
            $.post('@Url.Action("Home", "Upload")', { files: finalPile }, function (data) {
                    console.log("POST done");
                });
    });

C# action code:

[HttpPost]
[ActionName("Upload")]
public ActionResult Upload(IEnumerable <HttpPostedFile> files)
{
        if (files != null)
        {
            foreach (var item in files)
            {
                if (item != null)
                {
                    string pathname = Path.Combine(@"D:\Projects\SavingFile\UploadedFiles", Path.GetFileName(item.FileName));

                    item.SaveAs(pathname);
                }
            }
        }
        return View();
}

Currently, when using drag and drop I am getting an error

0: Invalid calling object

in Edge and

Uncaught TypeError: Illegal invocation

in Chrome, which is not very helpful. And when selecting file from <input> I get this error message:

HTTP404: NOT FOUND - The server has not found anything matching the requested URI (Uniform Resource Identifier).
(XHR)POST - http://localhost:51348/Upload/Home


Solution

  • There were couple of problems.

    1. jQuery.ajaxSettings.traditional = true was required to pass the array to the IEnumerable
    2. '@Url.Action("Home", "Upload")' -> '@Url.Action("Upload")'

    This might fix stuff for some.

    However, the call was successful but IEnumerable was always empty and fix to that is here: How to upload files using ajax to asp.net mvc controller action