【问题标题】:How to Upload file using AngularJS in MVC如何在 MVC 中使用 AngularJS 上传文件
【发布时间】:2019-12-10 12:24:57
【问题描述】:

由于我是 AngularJS 的新手,我不知道如何使用 AngularJS 在 MVC 中上传文件。 我正在尝试上传一些没有任何特定类型或扩展名的文件,但失败了。

我创建了一个 javascript 文件,它有 -

这里是serviceJS-

    var app = angular.module("app", []);        
    app.service('FileUploadService', ['$http', function ($http) {      
            this.uploadFileToUrl = function (file,  uploadUrl) {    
            var fd = new FormData();   
            fd.append('file', file);   
            $http.post(uploadUrl, fd, {   
                transformRequest: angular.identity,   
                headers: { 'Content-Type': undefined }   
            })   
            .success(function () {   
            })    
            .error(function () {    
            });     
        }   
    }]);

这是控制器部分-

    app.controller('FileUploadController', ['$scope', 'FileUploadService', function($scope, FileUploadService) { 
            $scope.uploadFile = function () {
            var file = $scope.myFile;
            console.log('file is ');
            console.dir(file);
            var uploadUrl = "/Home/FileUploadFromAngular";
            FileUploadService.uploadFileToUrl(file, uploadUrl);
        };
    }]);

而且,在视图页面中,

 <script src="~/Scripts/angular.min.js"></script>
<script src="~/Scripts/AngScript/FileUpload.js"></script>
<script src="~/Scripts/angular-ui/ui-bootstrap.min.js"></script>
    <div ng-controller="FileUploadController">
        <input type="file" ng-model="myFile" />
        <button ng-click="uploadFile()">Upload</button>
    </div>

它在控制器中将 myFile 视为未定义。我无法调试这个。
提前致谢。

【问题讨论】:

标签: javascript angularjs asp.net-mvc


【解决方案1】:

您不能将&lt;input type="file"&gt; 绑定到$scope 变量。您将需要创建一个指令来捕获文件输入标记的onchange event。例如&lt;input type="file" name="myFile" file-upload/&gt;,指令如下所示:

angular.module("app.directives", []).directive('fileUpload', function () {
return {
    scope: true,
    link: function (scope, el, attrs) {
        el.bind('change', function (event) {
            var files = event.target.files;
            //iterate files since 'multiple' may be specified on the element
            if(files.length == 0){
                scope.$emit("fileSelected", { file: null, field: event.target.name });
            } else{
                for (var i = 0;i<files.length;i++) {
                    //emit event upward
                    scope.$emit("fileSelected", { file: files[i], field: event.target.name });
                }
            }
        });
    }
};
});

之后,您可以像这样在控制器中捕获广播:

$scope.$on("fileSelected", function (event, args) {
    $scope.$apply(function () {
        switch (args.field) {
            case "myFile":
                $scope.myFile = args.file;
                break;
            default:
                break;
        }
    });
});

你的服务方法可以是这样的:

this.uploadFileToUrl = function (file,  uploadUrl) { 
    return $http({
        method: 'POST',
        url: uploadUrl,
        headers: { 'Content-Type': undefined },
        transformRequest: function() {
            var formData = new FormData();
            if(file){
               formData.append("myFile", file); 
            }
            return formData;
        }
    })
}

【讨论】:

  • 感谢您的快速响应.. 仍然收到 injector 错误。你能告诉我如何在事件 onchange 中调用范围变量吗?
  • 未捕获的错误:[$injector:nomod] errors.angularjs.org/1.5.0/$injector/nomod?p0=app.directives
  • 哎呀,那是因为 oyu 还没有 angular app.directives 模块。我编辑了我的代码。
  • 谢谢,这个问题已经解决了.. 但现在它说文件未定义并出现 500 内部服务器错误:(
  • 那么你必须调试你的后端:) 我不知道那里有什么问题。
【解决方案2】:

试试这个。 控制器

/**** 文件上传 *****/

   $scope.upload = [];
    $scope.fileUploadObj = {
        "ID": $rootScope.filesReturn.id
    }

    $scope.onMultiFileSelect = function ($files) {
        //$files: an array of files selected, each file has name, size, and type.
    $scope.errArr = [];
    for (var i = 0; i < $files.length; i++) {
        var $file = $files[i];
        if ($file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || $file.type === 'application/vnd.ms-excel') {
            (function (index) {
                $scope.upload[index] = $upload.upload({
                    url: host + 'api/Return/ReturnUpload',
                    method: "POST",
                    data: { fileUploadObj: $scope.fileUploadObj },
                    file: $file
                }).progress(function (evt) {
                    // get upload percentage Can hook to some Load view thing
                    //console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
                }).success(function (data, status, headers, config) {
                    // file is uploaded successfully
                    $scope.chkErr();
                }).error(function (data, status, headers, config) {
                    // file failed to upload
                    $scope.setErr(data.returnDataErr);
                    $scope.chkErr();
                });
            })(i);
        }
        else
        {
            $scope.setErr($file.name + " is not an .xls .xlsx");
            $scope.chkErr();
            (i);
        }
    }//END FOR
    $scope.abortUpload = function (index) {
        $scope.upload[index].abort();
    }
}
//check if there is errormsg in array.
$scope.chkErr = function () {
    if ($scope.errArr.length > 0) {
        //IS ERROR
        $scope.errorUpload = true;
        $scope.$apply();
        //$scope.errorMessage = data.returnDataErr;
    }
    else {
        //IS SUCCESS
        $scope.noFiles = false;
        $scope.errorUpload = false;
        $scope.getFiles();
    }
}

查看

                            <div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">
                                <input style="float:left" type="file" ng-file-select="onMultiFileSelect($files)" multiple>
                                <div style ="float:left">
                                    <a ng-show="!noFiles" class=" btn btn-default btn-xs" ng-click="confirmClick() && deleteItem()" confirm-click data-localize="DELETE">
                                        Delete All
                                    </a>
                                </div>
                            </div>

API 或 MVC 控制器

  [Route("ReturnUpload")]
    [HttpPost]
    public async Task<HttpResponseMessage> ReturnUpload()
    {
        if (!Request.Content.IsMimeMultipartContent())
        {
            this.Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
        }

        try
        {
            var provider = GetMultipartProvider();
            var result = await Request.Content.ReadAsMultipartAsync(provider);

            //JSON data from upload ( returns id )
            var returns = GetFormData<UploadReturnBindingModel>(result) as UploadReturnBindingModel;

            //Get original FileName from result
            var originalFileName = GetDeserializedFileName(result.FileData.First());

            //Get data from UplaodedFile info.  paths created time etc.
            var uploadedFileInfo = new FileInfo(result.FileData.First().LocalFileName);

            var ret = db.ReturnRecords.Single(a => a.id == returns.ID);
            var tenantId = db.Users.Find(User.Identity.GetUserId()).Tenant.id;
            var entityId = ret.entityId;
            if (ret.status == ReturnStatus.Converting.ToString())
            {
                // If you want to send something to the .error callback, 
                var returnDataErr = "Convertion in Progress, try again later";
                return this.Request.CreateResponse(HttpStatusCode.BadRequest, new { returnDataErr });
            }

            var ToDir = uploadedFileInfo.DirectoryName + "\\" + tenantId + "\\" + entityId + "\\" + returns.ID + "\\Upload\\";
            if (!Directory.Exists(ToDir))
            {
                Directory.CreateDirectory(ToDir);
            }
            else if (System.IO.File.Exists(ToDir + originalFileName))
            {
                var toDelete = db.FileRecords.Single(a => a.path + a.name == ToDir + originalFileName && a.returnId == returns.ID);
                db.FileRecords.Remove(toDelete);
                System.IO.File.Delete(ToDir + originalFileName);
            }
            System.IO.File.Move(uploadedFileInfo.FullName, ToDir + originalFileName);

            var file = new Portal.Models.File();
            file.userName = db.Users.Find(User.Identity.GetUserId()).UserName;
            file.name = originalFileName;
            file.path = ToDir;
            file.returnId = returns.ID;
            file.timeStamp = DateTime.Now;
            //var createdTime = uploadedFileInfo.CreationTime;
            //var currentUser =  User.Identity.GetUserId();
            db.FileRecords.Add(file);


            // Update the ret status that files has been uploaded.
            ret.status = ReturnStatus.DocumentsUploaded.ToString();

            db.SaveChanges();


        }
        catch(Exception ex)
        {
            // If you want to send something to the .error callback, use the HttpStatusCode.BadRequest instead
            log.Error(ex);
            var returnDataErr = "Failed creating file";
            return this.Request.CreateResponse(HttpStatusCode.BadRequest, new { returnDataErr });
        }
        // Through the request response you can return an object to the Angular controller
        // You will be able to access this in the .success callback through its data attribute
        var returnDataOk = "OK";
        return this.Request.CreateResponse(HttpStatusCode.OK, new { returnDataOk });
    }

【讨论】:

    【解决方案3】:
    <input class="input-sm" type="file" ng-model="Registration_CTRL.IDProdf" onchange="angular.element(this).scope().FN_UPLOAD_FILE(event)" multiple />
    


    $scope.FN_UPLOAD_FILE = function (evt) {
            var _file = new File([""], evt.target.file);
            var a = evt.target.files;
            var _formData = new FormData();
            _formData.append("IDPROOF", evt.target.files[0]);
            _formData.append("EMPID", $scope.Registration_CTRL.ID);
            $http({
                method: 'POST',
                url: '@Url.Action("Upload_Employee_IDProof", "Registration")',
                headers: { 'Content-Type': undefined },
                data: _formData
            }).then(function (data) {
                $scope.Registration_CTRL.IDProdf = data.data.aaData;
            });
        }
    

    [HttpPost]
    public JsonResult Upload_Employee_IDProof()
    {
        string _fileName = "";
        try
        {
            if (Request.Files.Count > 0)
            {
                var _empid = int.Parse(Request.Form["EMPID"]);
                var _file = Request.Files[0];
                var _fName = Request.Files["IDPROOF"].FileName;
                var _dotIndex = _fName.LastIndexOf('.');
                var _ext = _fName.Substring(_dotIndex);
                var _configpath = RequestHelpers.RequestHelpers.GetConfigurationValue("IDProofPath");
                _fileName = _empid + "_IDPROOF" + _ext;
                var _dirPath = Server.MapPath(_configpath);
                var _filePath = Server.MapPath(_configpath) + _fileName;
                if (System.IO.Directory.Exists(_dirPath))
                {
                    if (System.IO.File.Exists(_filePath))
                    {
                        System.IO.File.Delete(_filePath);
                    }
                    _file.SaveAs(_filePath);
                }
                else
                {
                    System.IO.Directory.CreateDirectory(_dirPath);
                    _file.SaveAs(_filePath);
                }
            }
        }
        catch (Exception ex)
        {
            return Json(new { aaData = ex.Message }, JsonRequestBehavior.AllowGet);
        }
        return Json(new { aaData = _fileName }, JsonRequestBehavior.AllowGet);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-13
      • 2015-09-13
      • 2014-01-27
      • 1970-01-01
      • 2021-09-19
      • 1970-01-01
      相关资源
      最近更新 更多