发送数据&从Angular到Web API的文件

时间:2016-09-09 00:19:34

标签: angularjs asp.net-mvc asp.net-web-api single-page-application

尝试发送一些数据&从AngularJS客户端到MVC Web API的附件(文件),它不起作用:我可以看到除附加文件以外的所有字段,显示为null

这是模特:

class Model{
 ... //the fields

public HttpPostedFileBase Photo { get; set; }//Attachment file, represented as an image
}

这是Web API:

public IHttpActionResult CreateModel([FromBody]Model model)
{
...
}

这是AngularJS代码:

(function () {
angular.module("application")
       .controller("homeCtrl", ["$scope", "entityService",
           function ($scope, entityService) {

               $scope.createModel = function (model)
               {
                   entityService.createModel(model)
                                .then(function (data) {
                                    console.log(data);
                                });
               };

               $scope.model = {
                   FirstName: "John",
                   LastName: "Doe"                 
               };

           }]);
})();


"use strict";
(function () {
 angular.module("application")
       .factory("entityService", ["akFileUploaderService", function (akFileUploaderService) {
           var createModel = function (model) {
               return akFileUploaderService.saveModel(model, "/api/CreateModel");
           };
           return {
               createModel: createModel
           };
       }]);
})();


(function () {
"use strict"
angular.module("akFileUploader", [])
    .factory("akFileUploaderService", ["$q", "$http",
           function ($q, $http) {

               var saveModel = function (data, url) {
                   var deferred = $q.defer();

                   $http({
                       url: url,
                       method: "POST",
                       data: JSON.stringify(data),   
                       transformRequest: angular.identity,
                       headers: { 'Content-Type': "application/json" }  
                   }).success(function (result) {
                       deferred.resolve(result);
                   }).error(function (result, status) {
                       deferred.reject(status);
                   });
                   return deferred.promise;
               };

               return {
                   saveModel: saveModel
               }

           }])
    .directive("akFileModel", ["$parse",
            function ($parse) {
                return {
                    restrict: "A",
                    link: function (scope, element, attrs) {
                        var model = $parse(attrs.akFileModel);
                        var modelSetter = model.assign;
                        element.bind("change", function () {
                            scope.$apply(function () {
                                modelSetter(scope, element[0].files[0]);
                            });
                        });
                    }
                };
            }]);
})(window, document);

这是HTML视图:

....
<div class="form-group">
        <label for="attachment">Photo:</label>
        <div class="col-md-10">
            <input type="file" name="attachment" class="form-control" data-ak-file-model="model.Photo" />
        </div>
    </div>


    <button type="button" ng-disabled="newForm.$invalid" ng-click="createModel(model)" class="btn btn-primary">
        Create
    </button>

1 个答案:

答案 0 :(得分:0)

WebApi没有(当前)使用与HttpPostedFileBase的MVC相同的机制。请参阅此question answer作为处理文件上传的示例 - 下面的示例(从答案中简化):

public async Task<HttpResponseMessage> AddFile()
{
    string root = HttpContext.Current.Server.MapPath("~/temp/uploads");
    var provider = new MultipartFormDataStreamProvider(root);
    var result = await Request.Content.ReadAsMultipartAsync(provider);

    foreach (var key in provider.FormData.AllKeys)
    {
        foreach (var val in provider.FormData.GetValues(key))
        {
            if (key == "aFormValue")
            {
                // do something with form data value
            }
        }
    }

    return this.Request.CreateResponse(HttpStatusCode.OK);
}

简而言之,您必须阅读请求的内容,选择文件(有时是形式)部分。您可以使用MultipartFormDataStreamProvider上的内置ReadAsMultipartAsync类和HttpContent方法执行此操作。

上面的方法假设您要保存到磁盘,当您想将文件放在其他地方时,它会变得有点棘手,您必须推出自己的MultipartFormDataStreamProvider实现来处理这个问题。