Search code examples
javascriptasp.net-mvcasp.net-corejquery-file-uploadajaxform

POST file list to controller in ajax post


I tried to upload documents but I couldnt pass to list my controllers parameter. My scenario is:

  1. user click to "choose file" button and pick the files and press done
  2. then my some functions get file list and pass to controller for save locally via POST merhod like below:

view side: (get file list)

   function saveDocuments(documentList) {
        if (documentList.length > 0)
        {
            var formList = new Array;
            for (var i = 0; i < documentList.length; i++) {
                var form = new FormData();
                var file = documentList[i];

                form.append('FormFile', file);
                formList.push(form);
                }
                 savePhysicalFile(formList);
              }
         }

view side: (post file list)

 function savePhysicalFile(formData)
    {
        if (formData != null)
        {
            $.ajax({
                url: "Installation/SavePhysicalPath",
                type: 'POST',
                dataType: "json",
                contentType: "multipart/form-data",
                data:formData,
                processData: false,
                contentType: false,
                success: function (result) {
                    console.log("Success", result);
                },
                error: function (data) {
                    console.log(data);
                }
            });
        }
    }

In my controller side; the parameter "model" is always null. I couldnt pass view side list here. How can I figure out ?

controller side

public JsonResult SavePhysicalPath([FromForm] List<FileModel> model)
        {
            var savingRootPath = @"C:\MyDocuments";

            //I'm doing save locally
           
            return Json(savingRootPath);
        }

model side

    public class FileModel
    {
        public string Files { get; set; }

        public IFormFile FormFile { get; set; }
    }


Solution

  • From your code,you may pay attention to two things here:

    1.For each property of the complex type, model binding looks through the sources for the name pattern prefix.property_name. If nothing is found, it looks for just property_name without the prefix.For model you receive in backend is a List,you need give the name like:[index].FormFile or model[index].FormFile.

    2.Your model has a IFormFile and your action receives a list model,if you only pass the IFormFile you need remove FromForm attribute and be sure do not have [ApiController].It is a known github issue and this has been moved to Next sprint planning milestone.

    Here is a whole working demo:

    View:

    <input type="file" multiple onchange="saveDocuments(this.files)"/>
    <div class="form-group">
        <input type="button" value="Submit" id="submit" class="btn btn-primary" />
    </div>
    
    @section Scripts
    {
        <script>
            function saveDocuments(documentList) {
                if (documentList.length > 0) {
                    var form = new FormData();
                    for (var i = 0; i < documentList.length; i++) {                    
                        var file = documentList[i];                    
                        //change here
                        form.append('model['+i+'].FormFile', file);
                    }
                    savePhysicalFile(form);
                }
            }    
            function savePhysicalFile(formData) {
                if (formData != null) {
                    $.ajax({
                        url: "/Installation/SavePhysicalPath",
                        type: 'POST',
                        dataType: "json",
                        contentType: "multipart/form-data",
                        data: formData,
                        processData: false,
                        contentType: false,
                        success: function (result) {
                            console.log("Success", result);
                        },
                        error: function (data) {
                            console.log(data);
                        }
                    });
                }
            }
        </script>
    }
    

    Controller:

    [HttpPost]
    public JsonResult SavePhysicalPath(List<FileModel> model)
    {
        var savingRootPath = @"C:\MyDocuments";
    
        //I'm doing save locally
    
        return Json(savingRootPath);
    }
    

    Result:

    enter image description here