将IFormFile更改为IList <iformfile>并发送$ http.post请求。 AngularJS,ASP.NET Core

时间:2019-03-02 15:12:13

标签: angularjs asp.net-core

我的示例仅适用于一个文件。我需要一个文件数组。我使用angularJS 1.7和asp.net-core 2.0

HTML

 <div class="post">
    <form>
        <textarea ng-model="Headline" name="Headline" rows="2" cols="63" class="form-control"></textarea>

        <textarea ng-model="BodyText" name="BodyText" rows="4" cols="63" class="form-control"></textarea>

        <input type = "file" file-model = "myFile" multiple/>

        <input id="Submit" class="btn btn-default" ng-click="createPost()" type="submit" value="Пост" />
    </form>
</div>

AgularJs控制器中的creatPost方法

 $scope.createPost = function () {
        var model = {
            Headline: $scope.Headline,
            BodyText: $scope.BodyText,
            ImgPost: $scope.myFile
        }
        $http({
                method: 'POST',
                url: '/api/Blog/create-post/',
                headers: {
                    'Content-Type': undefined
                },
                data: model,
                transformRequest: function (data, headersGetter) {
                    var formData = new FormData();
                    angular.forEach(data, function (value, key) {
                        formData.append(key, value);
                    });

                    return formData;
                }
            })
            .then(function onSuccess(response) {
                if (response.data = "Ok") {
                    $window.location.reload();
                }
            })


            .catch(function onError(response) {
                console.log("Error")
            });
    }

C#中的模型

[ScaffoldColumn(false)]
    public int Id { get; set; }

    [ScaffoldColumn(false)]
    public string User { get; set; }

    [Required(ErrorMessage = "")]
    [StringLength(100, MinimumLength = 1, ErrorMessage = "")]
    public string Headline { get; set; }

    [Required(ErrorMessage = "")]
    [StringLength(1000, MinimumLength = 1, ErrorMessage = "")]
    public string BodyText { get; set; }

    [ScaffoldColumn(false)]
    public DateTime? Date_Time { get; set; }

    public IFormFile ImgPost { get; set; }

和方法签名

    [HttpPost]
    [Route("create-post")]
    public async Task<object> PostSaveOnFile(PostViewModel model)
    {

我需要如何在#public IFormFile ImgPost {get;组; } 并在我的angularJS控制器上进行更改,我应该能够发送文件数组。谢谢。

据我所知,我在fileReader的伪造中遇到的问题

(function (angular) {
    angular.module('app').directive('fileModel', ['$parse', function ($parse) {
      return {
         restrict: 'A',
         link: function(scope, element, attrs) {
            var model = $parse(attrs.fileModel);
            var modelSetter = model.assign;

            element.bind('change', function() {
               scope.$apply(function() {
                  modelSetter(scope, element[0].files[0]);
               });
            });
         }
      };
   }]);
})(window.angular);

如果我将C#模型更改为IList或IEnumerable,它将只是第一个文件。我也不明白如何将我的矫正视力更改为数组

2 个答案:

答案 0 :(得分:2)

首先,您需要更新fileModel指令以设置文件数组而不是单个文件。您可以使用this answer,但生成的数组将具有FileList类型,建议您将其转换为Array,因为与其他代码更改结合起来,它会更加灵活

app.directive('fileModel', ['$parse', function ($parse) {
  return {
     restrict: 'A',
     link: function(scope, element, attrs) {
        var model = $parse(attrs.fileModel);
        var modelSetter = model.assign;

        element.bind('change', function() {
           scope.$apply(function() {
              modelSetter(scope, Array.from(element[0].files));
           });
        });
     }
  };
}]);

为了使ASP.NET Core正确绑定Array(或List),您需要将具有相同键的所有数组值添加到FormData。例如,如果您有

public List<string> Strings { get; set; }

您将需要使用Strings键添加值

formData.append("Strings", "value1");
formData.append("Strings", "value2");
formData.append("Strings", "value3");

因此,您需要更新transformRequest函数以将文件数组正确添加到FormData

function (data, headersGetter) {
    var formData = new FormData();
    angular.forEach(data, function (value, key) {
        //you could check if value is FileList
        //but your model can hold array of primitive values like ["val1", "val2", "val3"]
        //this single check for Array covers all cases
        //and you don't need to have different check for FileList
        if (value instanceof Array) {
            for (var i = 0; i < value.length; i++) {
                formData.append(key, value[i]);
            }
            return;
        }

        formData.append(key, value);
    });

    return formData;
}

答案 1 :(得分:1)

  

我也不了解如何将我的矫正视力更改为数组

app.directive('fileModel', ['$parse', function ($parse) {
  return {
     restrict: 'A',
     link: function(scope, element, attrs) {
        var model = $parse(attrs.fileModel);
        var modelSetter = model.assign;

        element.bind('change', function() {
           scope.$apply(function() {
              ̶m̶o̶d̶e̶l̶S̶e̶t̶t̶e̶r̶(̶s̶c̶o̶p̶e̶,̶ ̶e̶l̶e̶m̶e̶n̶t̶[̶0̶]̶.̶f̶i̶l̶e̶s̶[̶0̶]̶)̶;̶
              modelSetter(scope, element[0].files);
           });
        });
     }
  };
}]);

更改modelSetter调用以返回数组。