使用打字稿将文件上传到控制器

Posted

技术标签:

【中文标题】使用打字稿将文件上传到控制器【英文标题】:Uploading file to controller using typescript 【发布时间】:2016-11-27 13:08:08 【问题描述】:

我将 ASP.NET MVC 5 用于 Web 应用程序的后端,将 Angular + Typescript 用于 Web 应用程序的前端。

我正在尝试将文件上传到服务器,但由于某种原因控制器没有将文件作为参数获取(控制器中的参数为空)。

我正在分享下面的代码。

提前致谢!

html

<input id="filePath" name="filePath" type="file" accept="image/*" />
<a id="uploadImage" ng-click="ctrl.uploadFile()">Upload</a>

打字稿:

// controller class:
uploadFile(): void 
    var filePathInput: any = $("#filePath");
    if (filePathInput[0].files) 
        var file: any = filePathInput[0].files[0];
        var resource: any = this.service.uploadFile();
        resource.save(file, (result: any) => 
            if (!result || !result.success) 
                alert("error");
             else 
                alert("ok");
            
        );
    


// service class:
uploadFile(): ng.resource.IResourceClass<IMyResource> 
    return this.$resource("/MyController/UploadImage", null,  method: "POST" );

后端控制器:

[HttpPost]
public JsonResult UploadImage([FromBody]HttpPostedFileBase file)

    if (file == null || file.ContentLength == 0)
    
        return NullParameterResponse();
    
    else
    
        file.SaveAs("/img/" + Path.GetFileName(file.FileName));
        return SuccessResponse();
    

【问题讨论】:

我注意到的第一件事是不同的 URL 段:UploadImage -> UploadChequeImage 对不起,这是我发布问题时的错误。这是因为我试图通过重命名方法来简化问题中的问题,但我没有看到那个。我刚刚编辑了这个问题来解决这个问题。控制器方法其实是前端调用的,但是参数(文件)始终为null。 【参考方案1】:

TransformRequest 函数:这会使您的请求作为 FormData 而不是作为 JSon 对象发送。

 formDataObject(data: any): any 
        var fd = new FormData();
        angular.forEach(data, function (value, key) 
            fd.append(key, value);
        );
        return fd;
    

在您的角度资源中,定义保存选项并传递您之前创建的 transformRequest 函数。

uploadChequeFile(): ng.resource.IResourceClass<IChequeLoanResource> 
        return this.$resource<IChequeLoanResource>("/Cheque/UploadChequeImage", null,
            
                save: 
                    method: "POST",
                    transformRequest: this.formDataObject,
                    headers:  'Content-Type': undefined, enctype: 'multipart/form-data' 
                
            );
    

在您的控制器中,只需从传递文件的资源中调用您的保存方法。

var chequeFilePathInput: any = $("#chequeFilePath");
        if (chequeFilePathInput[0].files) 
            var resource: ng.resource.IResourceClass<services.IChequeLoanResource> = this.uLendService.uploadChequeFile();
            resource.save( "files": chequeFilePathInput[0].files[0] , (result: any) => 
                if (!result || !result.success) 
                    this.errorMessage = "Error al subir la imagen al servidor. Por favor contáctanos si el error persiste.";
                 else 
                    this.chequeLoan.cheque.filePath = result.message;
                    this.saveChequeLoan();
                
            );
         else 
            this.errorMessage = "La imagen del cheque es requerida.";
        

最后,您的控制器必须接收 IList 参数(与您的角度控制器中定义的名称相同)

public JsonResult UploadChequeImage(IList<IFormFile> files)
    
        try
        
            if (files != null && files.Count > 0)
            
                return CreateResponse(true, CreateFile(files[0], @"img\cheques"));
            

【讨论】:

以上是关于使用打字稿将文件上传到控制器的主要内容,如果未能解决你的问题,请参考以下文章

我可以使用打字稿将对象键限制为枚举值吗?

为啥打字稿将联合中的属性标记为不存在?

打字稿将自定义对象分配给任何对象

使用Angular或打字稿将字符串的第一个字母大写[重复]

打字稿将联合转换为交集[重复]

打字稿将数组转换为 JSON