Angular / Web API 2使用StreamContent或ByteArrayContent返回无效或损坏的文件

Adr*_*ian 6 c# memorystream asp.net-web-api angularjs asp.net-web-api2

我正在尝试在ASP.NET Web API控制器中返回文件。此文件是动态生成的PDF,保存在MemoryStream中。

客户端(浏览器)成功接收到文件,但是当我打开文件时,我看到所有页面都完全空白。

问题是,如果我使用相同的MemoryStream并将其写入文件,则此磁盘文件将正确显示,因此我认为问题与通过Web传输文件有关。

我的控制器如下所示:

[HttpGet][Route("export/pdf")]
public HttpResponseMessage ExportAsPdf()
{
    MemoryStream memStream = new MemoryStream();
    PdfExporter.Instance.Generate(memStream);

    memStream.Position = 0;
    HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
    result.Content = new ByteArrayContent(memStream.ToArray()); //OR: new StreamContent(memStream);
    return result;
}
Run Code Online (Sandbox Code Playgroud)

尝试一下,如果我将流写入磁盘,则会正确显示:

[HttpGet][Route("export/pdf")]
public HttpResponseMessage ExportAsPdf()
{
    MemoryStream memStream = new MemoryStream();
    PdfExporter.Instance.Generate(memStream);

    memStream.Position = 0;
    using (var fs = new FileStream("C:\\Temp\\test.pdf", FileMode.OpenOrCreate, FileAccess.ReadWrite))
    {
        memStream.CopyTo(fs);
    }

    return null;
}
Run Code Online (Sandbox Code Playgroud)

不同之处在于:

  • PDF已保存在磁盘上:34KB
  • 通过Web传输的PDF:60KB(!)

如果我比较两个文件的内容,主要区别是:

文件差异

左侧是通过Web传输的PDF。在右侧,PDF已保存到磁盘。

我的代码有问题吗?也许与编码有关?

谢谢!

Adr*_*ian 4

嗯,结果是客户端(浏览器)的问题,而不是服务器的问题。我在前端使用 AngularJS,因此当收到响应时,Angular 会自动将其转换为 Javascript 字符串。在该转换中,文件的二进制内容以某种方式改变了......

基本上,它是通过告诉 Angular 不要将响应转换为字符串来解决的:

$http.get(url, { responseType: 'arraybuffer' })
.then(function(response) {
    var dataBlob = new Blob([response.data], { type: 'application/pdf'});
    FileSaver.saveAs(dataBlob, 'myFile.pdf');
});
Run Code Online (Sandbox Code Playgroud)

然后在Angular File Saver服务的帮助下将响应保存为文件。