【问题标题】:To change IFormFile to IList<IFormFile> and sent $http.post request. AngularJS, ASP.NET Core将 IFormFile 更改为 IList<IFormFile> 并发送 $http.post 请求。 AngularJS、ASP.NET 核心
【发布时间】:2019-03-03 08:48:23
【问题描述】:

我的示例仅适用于一个文件。我需要一组文件。我使用 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,它将只是第一个文件。我不明白如何将我的指令更改为数组

【问题讨论】:

    标签: angularjs asp.net-core


    【解决方案1】:

    首先您需要更新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;
    }
    

    【讨论】:

      【解决方案2】:

      我不明白如何将我的指令更改为数组

      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 调用以返回一个数组。

      【讨论】:

      • 没有帮助。现在在我的模型 ImgPost 在 api 控制器中为 null :(
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-20
      • 1970-01-01
      • 2020-12-09
      • 2021-09-12
      • 1970-01-01
      • 2019-05-03
      相关资源
      最近更新 更多