将文件从MVC 5下载到Angular 2

我有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); }); } 

请求进入服务器端。 该arrays已下载。 我想我的问题在于客户端。 谁能帮我吗?

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

  1. 将bytearray返回给浏览器后,您可以执行以下操作: 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); 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),并将该路由重定向到返回你的文件结果。

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

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

 any message 

对于所有未来的读者,我在这里总结一下。 根据EsdF的建议和peinearydevelopment的建议,我现在有了一个有效的解决方案。 在请求中将responseType指定为ArrayBuffer是最关键的部分,下载技巧非常有用。

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

替代方案2:openPictureInNewWindow方法是一种简单直接的方法。 缺点是它将呈现一个奇怪的URL,如下所示:blob: http:// localhost / 037713d1-a8b9-4fe3-8c43-ee5998ffdc5d 。

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

 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); }