IFormFile is always empty in Asp.Net Core WebAPI

I have a problem here when I am trying to push data with angularjs controller. But what ever I do (IFormFile file) is always empty. There are only some examples with razor syntax but no examples how to do it with angular or jquery.

HTML:

<form class="form-body" enctype="multipart/form-data" name="newFileForm" ng-submit="vm.addFile()"><input type="file" id="file1" name="file" multiple ng-files="getTheFiles($files)"/></form>

Directive:

(function() {
'use strict';

angular
    .module('app')
    .directive('ngFiles', ['$parse', function ($parse) {

    function fn_link(scope, element, attrs) {
        var onChange = $parse(attrs.ngFiles);
        element.on('change', function (event) {
            onChange(scope, { $files: event.target.files });
        });
    };

    return {
        link: fn_link
    };
    }]);
})();

Controller

var formdata = new FormData();
    $scope.getTheFiles = function ($files) {
        angular.forEach($files, function (key, value) {
            formdata.append(key, value);
        });
    };

vm.addFile = function () {                                              
        var xhr = new XMLHttpRequest();
        xhr.open('POST', url, true);
        xhr.setRequestHeader("Content-Type", "undefined");
        xhr.send(formdata);          
    }

Asp.net core webapi:

[HttpPost]
    public async Task<IActionResult> PostProductProjectFile(IFormFile file)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        ....
        return ...;
    }

I have also tried to do it with formdata, as it is constructed when you post it with razor syntax. Something like this:

dataService.addFile(formdata, {
            contentDisposition: "form-data; name="files"; filename="C:\Users\UserName\Desktop\snip_20160420091420.png"",
            contentType: "multipart/form-data",
                    headers: {
                        "Content-Disposition": "form-data; name="files"; filename="C:\Users\UserName\Desktop\snip_20160420091420.png"",
                        'Content-Type': "image/png"
                    },
                    fileName: "C:\Users\UserName\Desktop\snip_20160420091420.png",
                    name: "files",
                    length : 3563
            }

Also instead of formData to provide raw file as I wrote in comment. But still nothing happens

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

IFormFile will only work if you input name is the same as your method parameter name. In your case the input name is ‘files’ and the method parameter name is ‘file’. Make them the same and it should work.

Method 2

This is how to do it with angularjs:

vm.addFile = function () {                      
                var fileUpload = $("#file").get(0);
                var files = fileUpload.files;
                var data = new FormData();
                for (var i = 0; i < files.length ; i++) {
                    data.append(files[i].name, files[i]);
                }


                $http.post("/api/Files/", data, {
                    headers: { 'Content-Type': undefined },
                    transformRequest: angular.identity
                }).success(function (data, status, headers, config) {

                }).error(function (data, status, headers, config) {

                });
}

And in web Api:

[HttpPost]
public async Task<IActionResult> PostFile()
{
 //Read all files from angularjs FormData post request
 var files = Request.Form.Files;
 var strigValue = Request.Form.Keys;
 .....
}

Or like this:

    [HttpPost]
    public async Task<IActionResult>  PostFiles(IFormCollection collection)
    {
        var f = collection.Files;                         

            foreach (var file in f)
            {
                //....
             }           
    }

Method 3

You can do it also with kendo upload much simpler:

$("#files").kendoUpload({
        async: {
            saveUrl: dataService.upload,
            removeUrl: dataService.remove,
            autoUpload: false                                            
        },
        success: onSuccess,
        files: files
    });

Method 4

From the answer of @Tony Steele.
Here is the code sample (Where to change/take care of)

.NET Core 3.1 LTS

[Route("UploadAttachment")]
[HttpPost]
public async Task<IActionResult> UploadAttachment(List<IFormFile> formFiles)
{
    return Ok(await _services.UploadAttachment(formFiles));
}

AngularJS

var formFiles = new FormData();
if ($scope.files != undefined) {
    for (var i = 0; i < $scope.files.length; i++) {
       formFiles.append('formFiles', $scope.files[i]);
    }
}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x