通过Angular和TypeScript下载文件

时间:2017-05-10 07:52:47

标签: c# api angular typescript

我在Angular项目中下载文件时出现问题。问题是,当我尝试导航到文件的URL时,文件会成功下载。但是如何在Angular中实现下载功能?

[VRoute("PassportAttachments/{id}", 1)]
[HttpGet]
[AllowAnonymous]
public HttpResponseMessage GetPassportAttachmentById(int individualId, [FromUri] int id = -1)
{
    try
    {
        var attachment = _passportAttachmentManager.FindById(id);

        string attachmentPath = HttpContext.Current.Server.MapPath(
            string.Format(ConfigurationManager.AppSettings["IndividualPassportsPath"], individualId.ToString()) + attachment.FileName);

        //string downloadUrl = Url.Content(attachmentPath).Replace("/Api/Contacts/PassportAttachments/~", "");

        //var result = new { DownloadUrl = downloadUrl, AttachmentTitle = attachment.Title };
        //return Ok(result);
        if (File.Exists(attachmentPath))
            return new FileContentResult(attachmentPath, attachment.Title, FileResultType.ImageContentResult);
        else
            return null;
    }
    catch (Exception ex)
    {
        Unit.Logger.Error(ex, ToString(), ActionContext.ActionArguments.ToList());
        return null;
        //return NotFound();
    }
}

FileContentResult构造函数:

public FileContentResult(string FilePath, string ResponeFileName, FileResultType fileResultType) : base(HttpStatusCode.OK)
{
    var stream = new FileStream(FilePath, FileMode.Open, FileAccess.Read);
    base.Content = new StreamContent(stream);
    base.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachments") { FileName = ResponeFileName };

    switch (fileResultType)
    {
        case FileResultType.ZipContentResult:
            base.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip");
            break;
        case FileResultType.ExcelContentResult:
            base.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            break;
        case FileResultType.PDFContentResult:
            base.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
            break;
        case FileResultType.ImageContentResult:
            base.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
            break;
    }
}

就像我说的那样,当我输入自己下载文件的URL(因此AllowAnonymous)时,一切正常。但是我应该使用或编写函数来使用TypeScript

下载文件
public DownloadAttachments(): void {
    if (this.SelectedPassportAttachments != null && this.SelectedPassportAttachments.length > 0) {
        if (this.SelectedPassportAttachments.length == 1) {
            this.service.DownloadSinglePassportAttachment(this.SelectedPassportAttachments[0].Id, this.IndividualId).subscribe((file: any) => {
                // download file (function)
            });
        }
        else {
            this.service.DownloadMultiplePassportAttachment(this.IndividualId, this.SelectedPassportAttachments.map(pa => pa.Id), this.SelectedPassportNumber).subscribe();
        }
    }
}

1 个答案:

答案 0 :(得分:0)

由于您使用的是Content-Disposition标头,浏览器会在尝试加载网址时自动触发下载对话框。

因此,您可以直接导航到下载位置,也可以在单独的窗口中打开下载位置(当出现下载对话框时,将在大多数浏览器中自动关闭):

// navigate to the URL:
window.location.href = downloadUrl;

// or open a new window
window.open(downloadUrl);

请注意,如果您在鼠标事件外部运行window.open(例如按钮点击),则弹出窗口阻止程序将阻止打开窗口。您可以通过在单击下载按钮时打开首先窗口来避免这种情况,然后稍后更改URL。像这样:

downloadAttachment() {
    const downloadWindow = window.open('about:blank');
    this.service.GetDownloadUrl(…).subscribe(downloadUrl => {
        downloadWindow.location.href = downloadUrl;
    });
}