Чтобы изменить IFormFile на IList <IFormFile>и отправить запрос $ http.post.AngularJS, ASP.NET Core - PullRequest
0 голосов
/ 02 марта 2019

Мой пример работает только с одним файлом.Мне нужен массив файлов.Я использую 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>

Метод creatPost в контроллере AgularJs

 $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 голосов
/ 03 марта 2019

Сначала вам нужно обновить директиву fileModel, чтобы установить массив файлов вместо одного файла.Вы можете использовать этот ответ , но полученный массив будет иметь тип 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 key

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;
}
0 голосов
/ 03 марта 2019

Я не понимал, как изменить мой дерективный элемент на массив

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, чтобы получить массив.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...