从angularjs将文件发布到web api时,Content-Type为null

时间:2017-03-14 21:39:30

标签: angularjs html5 file-upload asp.net-web-api2 angular-http

我正在尝试使用AngularJs应用程序中的web api上传文件。以下是我的代码。

app.controller('RFCController', ['$scope', '$http', function ($scope, $http) {

    $scope.getFileDetails = function (e) {

        $scope.files = [];
        $scope.$apply(function () {

            // STORE THE FILE OBJECT IN AN ARRAY.
            for (var i = 0; i < e.files.length; i++) {
                $scope.files.push(e.files[i])
            }

        });
    };

    $scope.uploadFiles = function () {

        //FILL FormData WITH FILE DETAILS.
        var data = new FormData();

        data.append("uploadedFile", $scope.files[0]);
        
        $http.post('../api/RFCService/upload', data, {
            headers:{'Content-Type':'multipart/form-data'}
        }).then(function (response) {
            alert("sucess!");
            },
            function (response) {
                alert("error!");
            });

    }
}]);
<div>
    <label for="image1">Image File</label>
    <input type="file" id="file" name="file" onchange="angular.element(this).scope().getFileDetail(this)" />
          
</div>
<div>
    <button ng-click="uploadFiles()">Submit</button>
</div>

这是我的网络API。它只是测试它是否会抛出错误。

[Route("api/RFCService/upload")]
    [HttpPost]
    public HttpResponseMessage PostFormData()
    {
        // Check if the request contains multipart/form-data.
        if (!Request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
        }

        return Request.CreateResponse(HttpStatusCode.OK);

    }

此代码始终抛出错误,指出不支持的媒体类型。当我调试web api时,我发现Request.Content.Headers.ContentType下的content-type为null。我在调用api时设置内容类型。有人可以帮我纠正这段代码吗?

2 个答案:

答案 0 :(得分:0)

上传由FormData API创建的对象时,将内容类型标题设置为undefined非常重要。

$scope.uploadFiles = function () {

    //FILL FormData WITH FILE DETAILS.
    var data = new FormData();

    data.append("uploadedFile", $scope.files[0]);

    $http.post('../api/RFCService/upload', data, {
        //headers:{'Content-Type':'multipart/form-data'}
        //IMPORTANT
        headers:{'Content-Type': undefined }
    }).then(function (response) {
        alert("sucess!");
        },
        function (response) {
            alert("error!");
        });

}

通常,$ http服务会覆盖内容类型为application/json的{​​{3}}。通过将标头设置为undefinedXHR Send Method会自动使用部件边界设置内容类型标头。强制没有内容边界的内容类型会导致问题。

更好 - 直接发送文件

对于内容类型multipart/form-data,数据为XHR API,这会增加33%的开销。只需直接发送文件:

$scope.uploadFiles = function () {

    //FILL FormData WITH FILE DETAILS.
    //var data = new FormData();

    //data.append("uploadedFile", $scope.files[0]);

    //USE file directly
    var file = $scope.file[0];

    return $http.post('../api/RFCService/upload', file, {
        //headers:{'Content-Type':'multipart/form-data'}
        //IMPORTANT
        headers:{'Content-Type': undefined }
    }).then(function (response) {
        console.log("success!");
        return response;
    }).catch(function (errorResponse) {
        console.error("error!");
        throw errorResponse;
    });
}

base64 encoded接受XHR Send API并为其创建合适的标头。

另请注意,示例会在记录后从file objects和正确链返回承诺。

较早版本的AngularJS

默认情况下,AngularJS $ http服务设置内容类型标头并将JavaScript对象序列化为JSON UTF-8字符串。现代版本的$ http服务检测Blob,File和FormData对象,并跳过序列化 $http service 。对于旧版本,请使用transformRequest: []配置以防止序列化。

$scope.uploadFile = function (url, file) {

    var config = {
        headers: { 'Content-Type': undefined },
        tranformRequest: []
    };

    return $http.post(url, file, config)
      .then(function (response) {
        console.log("success!");
        return response;
    }).catch(function (errorResponse) {
        console.error("error!");
        throw errorResponse;
    });

}

答案 1 :(得分:0)

最后,这就是我如何运作的方式。请参阅下面的angularjs的电话。

&#13;
&#13;
 $scope.uploadFiles = function () {

        //FILL FormData WITH FILE DETAILS.
        var data = new FormData();
        var file = $scope.files[0];

        data.append("uploadedFile", file);
        
        $http({
            url: '../api/RFCService/upload',
            method: 'Post',
            data: data,
            headers: { 'Content-Type': undefined},
            transformRequest: angular.identity

        }).then(function (response) {
                alert("sucess!");
                },
                function (response) {
                    alert("error!");
                });
    }
&#13;
&#13;
&#13;

我不得不添加transformRequest。感谢georgeawg指向正确的方向。