简体   繁体   中英

Download file from Web API Core - Angular 7

I'm trying to download a file from the server but the file is not displaying it's original content instead it's displaying [object Object].

WEB API CORE

[Authorize(AuthenticationSchemes = "Bearer")]
[HttpGet]
public HttpResponseMessage DownloadContractFile(string fileName)
{
    string contentRootPath = _hostingEnvironment.ContentRootPath;
    var folderName = Path.Combine(contentRootPath, FileHandler.ContractFilePath, Convert.ToInt32(User.Identity.Name).ToString());

    var path = Path.Combine(folderName, fileName);

    var memory = new MemoryStream();

    HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
    using (var stream = new FileStream(path, FileMode.Open))
    {
        result.Content = new StreamContent(stream);
        result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
        result.Content.Headers.ContentDisposition.FileName = Path.GetFileName(path);
        result.Content.Headers.ContentType = new MediaTypeHeaderValue(FileHandler.GetContentType(path)); // Text file
        result.Content.Headers.ContentLength = stream.Length;

        return result;
    }
}

Angular Code: Service method

  downloadContractFile(fileName: string) {

    const obj: any = { fileName: fileName };

    const httpParams: HttpParamsOptions = { fromObject: obj } as HttpParamsOptions;

    const httpOptions = {
      params: new HttpParams(httpParams),
      headers: new HttpHeaders({
        'Content-Type': 'application/octet-stream',
        'Authorization': 'Bearer ' + this.jwt.getToken
      })
    };   


    return this.http.get<Array<any>>(`${this.settings.getApiSettings('uri')}/api/contract/DownloadContractFile`, httpOptions).map( /// <<<=== use `map` here
      (response) => {

        if (response["status"] == 401) {
          this.jwt.redirectToLogin();
        }
        else if (response["status"] < 200 || response["status"] >= 300) {
          throw new Error('This request has failed ' + response["status"]);
        }
        let data = response;
        return data;
      }
    );

  }

Component.ts

  downloadFile(fileName) {

    this.js.checkTokenValid().subscribe(res => {

      if (res == null)
        this.js.redirectToLogin();
      else {

        this.conc.downloadContractFile(fileName).subscribe(respData => {

          console.log(respData);

          this.type = respData.content["headers"][1]["value"][0];

          this.downFile(respData.content, this.type, fileName);

        }, error => {

        });

      }
    });

  }

  downFile(data: any, type: string, fileName: string) {

    var blob = new Blob([data], { type: type });
    var url = window.URL.createObjectURL(blob);

    saveAs(blob, fileName);

    //var fileURL = URL.createObjectURL(res);
    //window.open(fileURL); // if you want to open it in new tab

  }

Component.html

<a href="javascript:void(0)" (click)="downloadFile(item.fileName);">download file</a>

Response Received

在此处输入图片说明

Received file content

在此处输入图片说明

This is my code which I using in the project to download the file.

Controller Code :

    [HttpGet("DownloadFile")]
    public async Task<IActionResult> DownloadFile(string fileName = "")
    {
        var response = await DownloadFileFromDatabase(fileName);
        if (response.IsSuccessStatusCode)
        {
            System.Net.Http.HttpContent content = response.Content;
            var contentStream = await content.ReadAsStreamAsync();
            var audioArray = ReadFully(contentStream);
            return Ok(new { response = audioArray, contentType = "audio/wav", fileName });
        }
        else
        {
            throw new FileNotFoundException();
        }
    }

Client Side Code:

  HandleBase64  (data , contentType,fileName ){ 
    let byteCharacters = atob(data);    
    let byteNumbers = new Array(byteCharacters.length);    
    for (var i = 0; i < byteCharacters.length; i++) 
        byteNumbers[i] = byteCharacters.charCodeAt(i);

    let byteArray = new Uint8Array(byteNumbers);    
    let blob = new Blob([byteArray], {type: contentType});
    if(contentType === "audio/wav"){
        var blobURL=URL.createObjectURL(blob);
        window.open(blobURL);       
    }
    else{
        var blobURL = window.URL.createObjectURL(blob);
        var anchor = document.createElement("a");
        anchor.download = fileName;
        anchor.href = blobURL;
        anchor.click();
    }
}

You can also simply return file using file stream in the controller side. This will automatically download the file no need to handle in client side

    return File(stream, "application/octet-stream"); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM