使用 Angular 6 将文件上传到 Web Api C#

Posted

技术标签:

【中文标题】使用 Angular 6 将文件上传到 Web Api C#【英文标题】:Upload a file using Angular 6 to Web Api C# 【发布时间】:2018-12-04 13:16:26 【问题描述】:

我有 Angular CLI 应用程序和 Dot net core 2.0 Web API。我需要将文件从 Angular 上传到 Web API。从 Web API 到服务器。当我使用 Http 时,它工作正常。使用 HttpClient 时,它不起作用。 这是我的 component.ts 代码:

fileChange(event, grdvalue) 
debugger;
let fileList: FileList = event.target.files;
if (fileList.length > 0) 
  let file: File = fileList[0];
  const formData: FormData = new FormData();
  let GridName = grdvalue;

  formData.append('file', file, file.name);
  formData.append('Id', this.userId);
  formData.append('GridValue', GridName)

  this.myService.PostFileToAzure(formData).subscribe(details => 
    debugger;
  ,
    (error) => 
      debugger;
    )
  
 

这是我的服务代码:

 PostFileToAzure(form) 
    debugger;
    var body = JSON.stringify(form);
    return this.http.post(this.baseApiURL + '/Interpretation/InterpreterFileUpload', form);

这是我的 Web API 代码:

[HttpPost("InterpreterFileUpload")]
    public async Task<IActionResult> InterpreterFileUpload()
    
        try
        

            var file = Request.Form.Files[0];
            HttpRequest formData = HttpContext.Request;
        
    

如何使用 HttpClient 从 Angular 发送文件到 Web API。我在 Web API 中遇到错误,例如“不正确的内容类型:应用程序/json”

【问题讨论】:

不要JSON.stringify你的表单 【参考方案1】:

在角度站点使用此代码

file: any;

onSelectFile($event, file) 
    this.file = file;
  


  uploadImage() 
    if (this.file.length === 0) 
      return;
    

    const formData = new FormData();

    for (let file of this.file)
      formData.append(file.name, file);

    const uploadReq = new HttpRequest('POST', `api/FileUpload`, formData, 
      reportProgress: true,
    );

    this.http.request(uploadReq).subscribe(event => 
      if (event.type === HttpEventType.UploadProgress) 
        this.progress = Math.round(100 * event.loaded / event.total);
      
    );
  

onSelectFile 应该在这样的输入上调用

<input #file type='file' multiple (change)="onSelectFile($event, file.files)">

并在您的 asp.net 站点上使用此代码

[Produces("application/json")]
    [Route("api/[controller]")]
    public class FileUploadController : Controller
    
    private IHostingEnvironment _hostingEnvironment;

    public FileUploadController(IHostingEnvironment hostingEnvironment)
    
      _hostingEnvironment = hostingEnvironment;
    

    [HttpPost, DisableRequestSizeLimit]
    public ObjectResult UploadFile()
    
      try
      
        var file = Request.Form.Files[0];
        string folderName = "Upload";
        string webRootPath = _hostingEnvironment.WebRootPath;
        string newPath = Path.Combine(webRootPath, folderName);
        if (!Directory.Exists(newPath))
        
          Directory.CreateDirectory(newPath);
        
        string fileName = "";
        if (file.Length > 0)
        
          fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
          string fullPath = Path.Combine(newPath, fileName);
          using (var stream = new FileStream(fullPath, FileMode.Create))
          
            file.CopyTo(stream);
          
        

        return Ok(fileName);
      
      catch (System.Exception ex)
      
        return BadRequest(ex.Message);
      
    
  

谢谢

【讨论】:

这是节省时间的答案,先生。 嗨,我如何访问服务器的响应? @Ali7091 上传的文件将上传到 wwwroot 文件夹中,因此您可以直接从那里访问该文件。示例 locahost:66363/Upload/filename.png @ElonMusk 不,我的意思是来自服务器的最终响应,我找到了答案,在event.body,谢谢【参考方案2】:

https://github.com/BhadraAnirban/angular_file_upload_net_core

该过程是使用 FormBody 中的 POST 调用从 Angular 发送 base64 字符串,并在 .net 核心将字符串转换为字节。

注意 - FormData 在 AWS Lambda 中无法正常工作,它会损坏文件。所以这也是在 AWS 中发送邮件或上传文件的更好方法。

html -

<form class="row">
    <input id="id" type="file" (change)="FileSelected($event.target.files);">
</form>
<div id="hidden_upload_item" style="display: none;"></div>

打字稿-

FileSelected(files)
    this.fileData = <File>files[0];
    this.FileName = this.fileData.name;
    let reader = new FileReader();
    var selectedFile = <File>files[0];

    reader.onload = function (readerEvt: any) 
        var arrayBuffer = readerEvt.target.result.toString().split('base64,')[1];     
        document.querySelector('#hidden_upload_item').innerHTML = arrayBuffer;
        this.Proceed();
    .bind(this);
    reader.readAsDataURL(selectedFile);

  

  Proceed()
  
    var item = document.querySelector('#hidden_upload_item').innerHTML;
    let formdata = new UploadFile();
    formdata.data = item;
    formdata.name = this.FileName;
    this.UploadDocument(formdata)
      .subscribe(event => 
        // Perform other operations
      , err => 
        this.InProgress = false;
      );
  

  UploadDocument(formData)
        const httpOptions = 
          headers: new HttpHeaders(
            'Content-Type': 'application/json'
          )
        ;
        return this.http.post('/api/document/uploaddocument', formData, httpOptions);
       

.net 核心 -

[HttpPost("uploaddocument"), DisableRequestSizeLimit]
public IActionResult UploadDocument([FromBody] FileModel fileModel)
        
            try
            
                    var value = fileModel.Data;
                    var byteArray = Convert.FromBase64String(value);
                    var fileExtension = Path.GetExtension(fileModel.Name);
                    var fileName = fileModel.Name;

                    /// Now save in Database or AWS

                
                return Ok();
            
            catch (Exception e)
            
                throw e;
            

                

 public class FileModel

    public string Data  get; set; 
    public string Name  get; set; 

【讨论】:

var byteArray = Convert.FromBase64String(value);如果不是base64字符串会引发异常。【参考方案3】:

我使用了@Elon Musk的解决方案,但是Request.Form.Files[0]给了我评估超时异常,所以为了处理它,我在.net端的Actionmethod中添加了Iformfile参数

public IActionResult UploadFile(IFormFile formfile)

【讨论】:

以上是关于使用 Angular 6 将文件上传到 Web Api C#的主要内容,如果未能解决你的问题,请参考以下文章

Angular 6 - 集成jQuery / JavaScript文件

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

Angular 6 项目刷新后显示 404 错误

使用 Angular2 将文件上传到 REST API

尝试将文件从一个 Web 上传到 API 时出错

如何使用添加按钮在 Angular 6 中上传多个文件?