如何使用 ASP.net Web API 和 Javascript 下载二进制文件?
How to download binary file using ASP.net Web API and Javascript?
我有一个 Web API 控制器,如下所示:
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web.Http;
using System.Threading.Tasks;
using System.IO;
namespace APIIntegration.Controllers
{
public class TestController : ApiController
{
// http://localhost/api/test
[HttpGet]
public async Task<HttpResponseMessage> Get()
{
Stream stream = streamWith256Bytes;
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentLength = stream.Length;
result.Content.Headers.ContentType =
new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = "foo.bin";
return result;
}
private static Stream streamWith256Bytes
{
get
{
MemoryStream stream = new MemoryStream();
for (int i = 0; i <256 ; i++)
{
stream.WriteByte(Convert.ToByte(i));
}
stream.Position = 0;
return stream;
}
}
}
}
简而言之,此控制器尝试将 256 字节的文件下载到浏览器。起初,它似乎可以工作,但是当检查下载的文件时,大小为 512 字节而不是预期的 256 字节并且 non-printable 字符被丢弃。
如何修改此代码以便正确下载二进制数据?
编辑: 我还应该提到我在这里看到了一个类似的问题:Problems with downloading pdf file from web api service 通过添加 content-length [=36] 解决了问题=],但这并没有为我解决这个问题。
编辑: 我修改了上面的源代码以提供一个完整的、有效的示例来说明如何重现。
编辑: 我发现当我在地址栏中键入地址时,上面的代码实际上可以正常工作,但是当使用 Javascript 启动下载,这就是我遇到的问题。
我找到了解决办法。在我的 Javascript 中,我使用 Angular 使用 Angular $http 服务启动文件下载。默认情况下,此服务将响应解释为文本。我不得不告诉 Angular 将响应解释为一个 blob,然后修复了所有问题。
我的工作代码如下所示:
function download(downloadUrl) {
$http({
url: downloadUrl,
responseType: "blob"
})
.then(function (response) {
var blob = new Blob([response.data], { type: "application/octet-stream" });
saveAs(blob, "foo.bin");
}, function (response) {
alert("error downloading file from " + downloadUrl);
});
}
我有一个 Web API 控制器,如下所示:
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web.Http;
using System.Threading.Tasks;
using System.IO;
namespace APIIntegration.Controllers
{
public class TestController : ApiController
{
// http://localhost/api/test
[HttpGet]
public async Task<HttpResponseMessage> Get()
{
Stream stream = streamWith256Bytes;
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentLength = stream.Length;
result.Content.Headers.ContentType =
new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = "foo.bin";
return result;
}
private static Stream streamWith256Bytes
{
get
{
MemoryStream stream = new MemoryStream();
for (int i = 0; i <256 ; i++)
{
stream.WriteByte(Convert.ToByte(i));
}
stream.Position = 0;
return stream;
}
}
}
}
简而言之,此控制器尝试将 256 字节的文件下载到浏览器。起初,它似乎可以工作,但是当检查下载的文件时,大小为 512 字节而不是预期的 256 字节并且 non-printable 字符被丢弃。
如何修改此代码以便正确下载二进制数据?
编辑: 我还应该提到我在这里看到了一个类似的问题:Problems with downloading pdf file from web api service 通过添加 content-length [=36] 解决了问题=],但这并没有为我解决这个问题。
编辑: 我修改了上面的源代码以提供一个完整的、有效的示例来说明如何重现。
编辑: 我发现当我在地址栏中键入地址时,上面的代码实际上可以正常工作,但是当使用 Javascript 启动下载,这就是我遇到的问题。
我找到了解决办法。在我的 Javascript 中,我使用 Angular 使用 Angular $http 服务启动文件下载。默认情况下,此服务将响应解释为文本。我不得不告诉 Angular 将响应解释为一个 blob,然后修复了所有问题。
我的工作代码如下所示:
function download(downloadUrl) {
$http({
url: downloadUrl,
responseType: "blob"
})
.then(function (response) {
var blob = new Blob([response.data], { type: "application/octet-stream" });
saveAs(blob, "foo.bin");
}, function (response) {
alert("error downloading file from " + downloadUrl);
});
}