将文件从 angularjs 发布到 Web api 时,Content-Type 为空

Content-Type is null while posting file to web api from angularjs

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

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 下的内容类型为空。我在调用 api 时设置内容类型。有人可以帮我更正此代码吗?

上传由 FormData API 创建的 objects 时,重要的是将内容类型 header 设置为 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 服务会覆盖 XHR Send Method with content type application/json. By setting the header to undefined, the XHR API 自动设置内容类型 header 与部分边界。强制使用没有内容边界的内容类型会导致问题。


更好的是——直接发送文件

对于内容类型 multipart/form-data,数据是 base64 encoded,这增加了 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;
    });
}

XHR Send API accepts file objects 并为他们创建合适的 header。

另请注意示例 returns 来自 $http service 的承诺并在记录后正确链接。


旧版本 AngularJS

AngularJS $http 服务,默认情况下,设置内容类型header 并将JavaScript objects 序列化为JSON UTF-8 字符串。 $http 服务的现代版本检测 Blob、文件和 FormData objects 并跳过序列化1。对于旧版本,配置 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;
    });

}

最后这就是我让它工作的方式。请参阅下面来自 angularjs 的电话。

 $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!");
                });
    }

我必须添加 transformRequest。感谢 georgeawg 指出正确的方向。