【问题标题】:Download file from MVC 5 to Angular 2将文件从 MVC 5 下载到 Angular 2
【发布时间】:2017-02-03 15:15:10
【问题描述】:

我有 C# 后端和 ASP.Net MVC 方面的经验。现在我正在对 Angular 2 进行第一次尝试。这需要时间,但我最喜欢它。现在我被困在一个简单的文件下载上。

我已经阅读了我在 Stackoverflow 上找到的所有示例,但我的示例仍然无法正常工作。

在服务器端我有这个 C# 代码:

    public ActionResult DownloadPicture(long id)
    {
        var bytes = System.IO.File.ReadAllBytes("images\dummy.jpg");
        return GetAttachement(bytes, "DummyFile.jpg");
    }

    private ActionResult GetAttachement(byte[] bytes, string fileName)
    {
        var contentType = MimeMapping.GetMimeMapping(fileName);
        var contentDisposition = new System.Net.Mime.ContentDisposition
        {
            FileName = fileName,
            Inline = true
        };
        Response.AppendHeader("Content-Disposition", contentDisposition.ToString());
        return File(bytes, contentType);
    }

在客户端我有这个 Typescript 代码:

public pictureDownload(id: number): void {
    let options = new RequestOptions({ search: new URLSearchParams("id=" + id) });
    this.http.get(this.urlPictureDownload, options).subscribe((data: any) => {
                // var blob = new Blob([data._body], { type: "image/jpeg" });
                // var url = window.URL.createObjectURL(blob);
                // window.open(url);
       });
 }

请求正在进入服务器端。阵列已下载。我想我的问题出在客户端。谁能帮帮我?

【问题讨论】:

  • 有趣 - 我没有 tried thisFileSaver.js。注意arraybuffer。嗯……
  • 您是否有理由不能只对文件使用普通的旧链接?这可能是最简单的。
  • 我知道,我真的很想这样做,但文件不在磁盘上。它们存储在后端存储中,因此我实际上将它们作为流保存。
  • 感谢 EsDF 提供链接。它真的很有帮助。我仍然有一些关于下载的问题。请参阅上面的更新。

标签: c# asp.net asp.net-mvc angular


【解决方案1】:

不管它的价值如何,这不仅仅是 Angular2 的问题。这似乎是浏览器(或可能是规范)的“问题”。我知道这种方法有几种不同的选择。

  1. 一旦字节数组返回到浏览器,你可以这样做: var pom = document.createElement('a'); pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(data)); pom.setAttribute('download', 'PICTURENAME.jpeg'); pom.style.display = 'none'; document.body.appendChild(pom); pom.click(); document.body.removeChild(pom);

  2. 我知道的另一种方法是在服务器上的临时路径上创建文件,然后将重定向结果返回给用户,并使用标识该文件的 id(通常是 GUID)并拥有该文件被重定向以返回您的文件结果的路由。

【讨论】:

    【解决方案2】:

    我在这里总结了所有未来的读者。根据 EsDF 的建议和 peinearydevelopment 的建议,我现在有了一个可行的解决方案。在请求中将 responseType 指定为 ArrayBuffer 是最关键的部分,下载技巧真的很有帮助。

    Alt 1:我认为凯西是对的。只要有可能,最简单的方法就是使用指向服务器资源的简单链接标签。在我的情况下,这不是一种选择,其他两种选择中的任何一种都将是有用的。

    Alt 2:方法 openPictureInNewWindow 是简单直接的方法。缺点是它会显示一个奇怪的 url,如下所示:blob:http://localhost/037713d1-a8b9-4fe3-8c43-ee5998ffdc5d

    Alt 3:另一种方法 downloadFile 将更进一步,创建一个临时链接标签,并利用它来下载文件。对于大多数用户来说,这看起来像是正常的方法。但它感觉不像是一种“Angular 2 方法”来操纵 DOM,但它是一种更加用户友好的方式,所以现在我将使用它。感谢所有的好意见!

    public pictureDownload(id: number) {
        let options = new RequestOptions({ search: new URLSearchParams("id=" + id), responseType: ResponseContentType.ArrayBuffer });
        this.http.get(this.urlPictureDownload, options).subscribe((data: any) => {
            //this.openPictureInNewWindow(data._body, "image/jpeg");
            this.downloadFile(data._body, "Screenshot_" + id + ".jpg", "image/jpeg");
        });
    }
    
    private openPictureInNewWindow(data: ArrayBuffer, contentType: string) {
        var blob = new Blob([data], { type: contentType });
        var url = window.URL.createObjectURL(blob);
        window.open(url);
    }
    
    private downloadFile(data: ArrayBuffer, fileName: string, contentType: string) {
        var blob = new Blob([data], { type: contentType });
        var url = window.URL.createObjectURL(blob);
    
        var link = document.createElement("a");
        link.setAttribute("href", url);
        link.setAttribute("download", fileName);
        link.style.display = "none";
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    }
    

    【讨论】:

    • 我在 angular1 中也遇到了困难。我确实从 db 获取了我的图像作为 bytearray,通过 webapi 将它们作为 json 隧道传输,并将结果插入到 img src 标记中。 (有效)但是,这有一个问题,即 json 变得相当大并且没有发生客户端缓存。 (我使用这种方法来获取小型头像图像,因此该主题留待未来改进)。
    【解决方案3】:

    如果您在浏览器中看到应用程序后端 URL 的图像。然后你可以直接在组件的标记中将它分配给 img 的 src,如下所示:

    假设您在组件中声明一个带有 imgURL 的字段,并使用您的后端图像操作方法对其进行初始化。那么在标记中你可以这样做

    <img src='{{imgURL}}' alt='any message'/>
    

    【讨论】:

    • 我可能应该对此更具体。我很想使用一个简单的 url,但文件不在磁盘上。它们存储在后端存储中,因此我实际上将它们作为流保存。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    • 1970-01-01
    • 2016-05-22
    • 2018-05-26
    • 2018-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多