0

EDIT:

Fixed it

Don't set your Content-Type to the string 'undefined' but use undefined instead, tends to work better.

I'm currently using this solution on how to convert a form (with file) to multipart/form-data but I will explain what I used for easy readability.

The backend is in ASP.NET 5.

I'm using this directive to bind the file input to an angular scope variable:

var app = angular.module('app', ['ngResource'])
                        .directive('filesModel', filesModelDirective);

function filesModelDirective() {
    return {
        controller: function ($parse, $element, $attrs, $scope) {
            var exp = $parse($attrs.filesModel);

            $element.on('change', function () {
                exp.assign($scope, this.files);
                $scope.$apply();
            });
        }
    };
}

and then doing this on the page:

<input type="file" files-model="newvisit.files" id="inputImage" />

This is used in ngResource, this is where it goes wrong. If you use debugger; you can see each of the values and its key, it also correctly attaches the file.

save: {
    method: 'POST',
    transformRequest: function (data) {
        if (data === undefined) return data;

        var fd = new FormData();
        angular.forEach(data, function (value, key) {
            if (value instanceof FileList) {
                if (value.length == 1) {
                    fd.append(key, value[0]);
                } else {
                    angular.forEach(value, function (file, index) {
                        fd.append(key + '_' + index, file);
                    });
                }
            } else {
                fd.append(key, value);
            }
        });

        return fd;
    },
    headers: { 'Content-Type': 'undefined', enctype: 'multipart/form-data' }
 }

I can create a multipart/form-data post in postman and the backend will accept it like seen below.

Custom post:

Creating custom post in Postman

Backend:

ignore the 'files' variable name please, already changed it to 'data'

Backend accepts and casts it

However when filling out the form on the webpage and letting Angular create a FormData() object it doesn't format(? no idea what to put here) it correctly, I intercepted this using Postman:

Postman intercept

And the backend will be unable to cast it.

Backend

As you can see the relevant headers 'Content-Type' and 'enctype' from the intercepted post are correctly set to 'undefined' and 'multipart/form-data'

Headers from intercepted post

I'm not sure if the problem lies somewhere with ASP.NET 5 but since it can accept a custom post I'm not sure.

EDIT: I just tried manually putting the headers 'Content-Type': 'undefined' and 'enctype': 'multipart/form-data' in my custom post and it doesn't work, is ASP.NET falling short here or am I doing something wrong?

EDIT2: I got my custom post working again by leaving the 'Content-Type' header unset and setting the 'enctype' header, I can't put 'Content-Type' on undefined or ASP.NET won't accept it. (if I look at the headers of the succesfull request HeaderContentType is set on undefined though)

Might this be a bug with ASP.NET?

Community
  • 1
  • 1
Matthew
  • 276
  • 2
  • 3
  • 15
  • exp.assign($scope, this.files); <-- the problem must be, the way you are manipulating file input. You can not copy or clone file input in html, if you do so underlying file will be lost, you can not access it anymore.. you have to work with directly with original input – Davit Tvildiani Mar 02 '16 at 13:47
  • @DavitTvildiani This might be a problem, not sure yet. Currently my issue lies with ASP.NET not accepting anything with the 'Content-Type': 'undefined' header – Matthew Mar 02 '16 at 13:58
  • @Matthew what appens if you change `Register([FromForm]` to `Register([FromBody]`? – Jose Rocha Mar 02 '16 at 15:30
  • @JoseRocha both are null – Matthew Mar 02 '16 at 15:35
  • @JoseRocha Fixed it, I was just being an idiot. – Matthew Mar 02 '16 at 16:00
  • @DavitTvildiani Fixed it, the exp.assign wasn't a problem by the way. – Matthew Mar 02 '16 at 16:01

1 Answers1

0

Don't put your Content-Type as a string 'undefined' kids, use undefined instead.

Matthew
  • 276
  • 2
  • 3
  • 15