当前位置: 首页 > 知识库问答 >
问题:

使用ASP.NET Web API在Angular 6中下载文件

柳逸春
2023-03-14

我们有一个带有ASP.NET web API后端的angular客户端(angular 6)。

要求:在后端服务的UI上下载文件。文件可以是任何类型-PDF、图像、文档、excel文件、记事本。

执行情况如下:

        [Route("api/Clients/{id:int}/Documents/{documentId}")]
        public HttpResponseMessage GetDocument(int id, string documentId)
        {
            string methodName = "GetDocument";
            logger.Info(methodName + ": begins. Id: " + id + ". Document Id: " + documentId);
            HttpResponseMessage response = null;

            try
            {
                var ticket = Request.Properties["Ticket"];
                var userName = ((Microsoft.Owin.Security.AuthenticationTicket)ticket).Identity.Name;
                ClientHelper clientHelper = new ClientHelper(userName);

                MemoryStream fileContent = new MemoryStream();

                //this._googleDriveManager.Get(documentId).CopyTo(fileContent);
                var fileData = this._googleDriveManager.Get(documentId);

                //Get file extension
                var document = clientHelper.GetDocumentbyDriveId(documentId);


                if (fileData.Length > 0)
                {
                    response = new HttpResponseMessage
                    {
                        StatusCode = HttpStatusCode.OK,
                        Content = new ByteArrayContent(fileData.ToArray())
                    };
                    response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
                    response.Content.Headers.ContentDisposition.FileName = document.FileName;
                    //response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
                    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                    response.Content.Headers.ContentLength = fileData.Length;
                }
                else
                {
                    response = Request.CreateResponse(HttpStatusCode.NotFound);
                }

            }
            catch (Exception exception)
            {
                //Log exception.
                logger.Error(methodName, exception);
                var errorModel = new { error = "There was an error." };
                response = new HttpResponseMessage();
                response.StatusCode = HttpStatusCode.InternalServerError;
            }

            logger.Info(methodName + " ends");
            return response;
        }

角度编码如下:

服务

import { Injectable } from '@angular/core';
import { AppSettings } from '../helpers/AppConstants';
import { HttpClient, HttpRequest, HttpEventType, HttpResponse, HttpHeaders } from '@angular/common/http';
import { Observable, Subject } from 'rxjs';
import { map, filter, catchError, mergeMap } from 'rxjs/operators';

@Injectable()
export class SharedService {

  constructor(private http: HttpClient) { }

  //This method gets the details of one client.
  public getDocument(id: number, fileId: string) {
    return this.http.get(AppSettings.DOCUMENTDOWNLOAD_ENDPOINT(id, fileId),
         {responseType: 'blob' as 'json'});

  }
}

组件

import { Component, OnInit, ViewChild, ElementRef, Input, Output, EventEmitter } from '@angular/core';
import { Document } from '../../../../models/document';
import { DocumentType } from '../../../../models/document-type';
import { SharedService } from '../../../../services/shared.service';
import { MatDialog, MatDialogConfig, MatTableDataSource, MatPaginator } from '@angular/material';

@Component({
  selector: 'app-documents',
  templateUrl: './documents.component.html',
  styleUrls: ['./documents.component.scss']
})
export class DocumentsComponent implements OnInit {

  constructor(private _sharedService: SharedService, public dialog: MatDialog) { }

  ngOnInit() {

  }

  fileDownload(document: any) {
    this._sharedService.getDocument(document.clientId, document.driveId)
      .subscribe(fileData => {
        console.log(fileData);
        let b: any = new Blob([fileData], { type: 'application/pdf' });
        var url = window.URL.createObjectURL(b);
        window.open(url);
      }
      );
  }
}

我们在这里错过了什么?

共有1个答案

澹台衡
2023-03-14

使用文件保护程序库解决了这个问题。

https://www.npmjs.com/package/file-saver

https://shekhargulati.com/2017/07/16/implementing-file-save-functionality-with-angular-4/

import { Injectable } from '@angular/core';
import { AppSettings } from '../helpers/AppConstants';
import { HttpClient, HttpRequest, HttpEventType, HttpResponse, HttpHeaders } from '@angular/common/http';
import { Observable, Subject } from 'rxjs';
import {saveFile, saveAs} from 'file-saver';
import { map, filter, catchError, mergeMap } from 'rxjs/operators';

@Injectable()
export class SharedService {
  constructor(private http: HttpClient) {}

  downloadFile(data: any, filename: string) {
    const blob = new Blob([data], { type: 'application/octet-stream' });
    saveAs(blob, filename);
  }

  //This method gets the details of one client.
  public getDocument(id: number, fileId: string, fileName: string) {

    this.http.get(AppSettings.DOCUMENTDOWNLOAD_ENDPOINT(id, fileId), {responseType: 'blob'})
      .subscribe((data) => this.downloadFile(data, fileName), error => console.log('Error downloading the file.'),
        () => console.info('OK'));
  }
}
 类似资料:
  • 问题内容: OK,所以我正在尝试使用Selenium导出文件。我的浏览器是IE。当我 单击导出按钮时,将出现一个本机Windows对话框。 弹出的图片 在此处输入图片说明 我必须单击“保存”按钮。为此,我尝试使用AutoIT但 不起作用。 这没有用。因此,我决定使用Robot类并执行键盘单击Atl + S,因为这还将使浏览器能够保存文件。那 也不起作用。 我认为Web驱动程序存在一些问题,因为我尝

  • 我正试图从一个包含阿根廷代表投票的公共网站自动下载excel文件。例如,来自以下页面:https://votaciones.hcdn.gob.ar/votacion/4108 我收到以下消息: selenium.common.exceptions。ElementClickInterceptedException:消息:元素在点(229480)处不可单击,因为另一个元素使其模糊 如果我尝试通过< c

  • 问题内容: 在Laravel应用程序中,我试图在视图内部实现一个按钮,该按钮可以允许用户下载文件而无需导航至任何其他视图或路径现在我有两个问题:(1)函数抛出以下 (2)“下载”按钮不应将用户导航到任何地方,而应仅在同一视图上下载文件,即“我的当前设置”,将视图路由到“ / download” 我正在尝试实现以下方法: 按键: 路线: 控制器: 问题答案: 尝试这个。 将无法正常工作,因为您必须提

  • 问题内容: 请求是一个非常不错的库。我想用它来下载大文件。问题是不可能将整个文件保留在内存中,我需要分块读取它。这是以下代码的问题 由于某种原因,它无法按这种方式工作。仍将响应加载到内存中,然后再将其保存到文件中。 更新 如果你需要一个小型客户端,可以从FTP下载大文件,则可以在此处找到它。它支持多线程和重新连接(它确实监视连接),还可以为下载任务调整套接字参数。 问题答案: 使用以下流代码,无论

  • 问题内容: 在SpringMVC应用程序中,有没有一种方法可以使用web.xml加载上下文? 问题答案: Spring可以轻松集成到任何基于Java的Web框架中。你需要做的就是在中声明并使用 设置要加载的上下文文件。 然后,你可以使用WebApplicationContext来获取bean的句柄。

  • 问题内容: 我正在尝试使用asyncTask下载文件,但无法正常工作,没有错误消息或什么都没有,只是不下载文件…我尝试了所有操作,但似乎并没有输入…任何人都知道可以是问题吗?我在手机上测试过,网址也可以。 问题答案: 我只运行了您的代码,它对我来说很好用。该图像已下载到sdcard。 请注意,请确保在AndroidManifest.xml中设置了以下权限: 这是我得到的日志(请注意,我添加了):

  • 问题内容: 我编写了一些代码来下载我所做的网络广播的一集。它获取剧集的URL,并获取保存它的位置。但是,它最多只能下载16MB,然后自动取消。我不完全确定要增加此值需要更改什么值。是否可以,有人可以指出正确的方向吗?谢谢! 下载代码: 问题答案: 快速查看transferFrom的文档: 好。 计数的值1 << 24(来自原始问题)等于16M 我想这就是您的问题的答案:-)

  • 问题内容: 我需要提供下载文件的链接,任何用户都必须隐藏该链接并且可以访问该链接,这是我的代码,没有任何错误,但是我什至无法打开下载对话框: 模板 脚本文件 问题答案: 首先,您不能“隐藏/不公开”基于Web的技术(HTML / CSS / JavaScript)应用程序中的链接。下载是由客户端处理的,因此Download / Link-URL必须是公共的。您可以尝试使用后端执行的编程语言(例如“